Taylor, thanks so much for the response. I just figured it out. Your suggestion was enough to guide me in the right direction.
The quick solution
Comment out lines 171 and 172 of this file in the Twitter-Async library: https://github.com/jmathai/twitter-async/blob/master/EpiOAuth.php#L171
The reason
The library makes an asynchronous curl to Twitter. The curl is supposed to pass its IP address within that call so Twitter knows where to respond. Since my server sits behind a load balancer, the server was passing an internal IP address in the curl request. Twitter’s response was never making it back to my server because Twitter can’t send to my internal IP Address.
And here’s the full background of the issue I was having
I have an iOS app that talks with my web API. A few of those API calls result in the server making a Twitter status. I have 3 environments dev, stage, and production.
Stage and Production both have load balancers that split traffic across a handful of webservers. Dev does not have a load balancer – it just has 1 webserver.
When an iOS app sends a request to the dev server, the dev server processes the request and makes the appropriate call to Twitter if necessary.
When the iOS app sends a request to the stage or production servers, the entire Exception that is thrown is the appended to the bottom of this message.
If I switch the DNS for the stage environment to skip the load balancer, the Twitter calls work fine from the stage environment.