An Appium timeout error is easiest to fix after the server log shows which layer stopped waiting. The same test run can fail because the server closed an idle session, an Android or iOS driver waited too long for app startup, or the client library gave up while Appium was still working.
The server-side idle timer is controlled by the appium:newCommandTimeout capability. Current Appium sessions default to 60 seconds, and a value of 0 disables the idle-command timer, but disabling it should be reserved for controlled debugging because abandoned sessions can keep devices and simulators busy.
Do not raise every timeout at once. Capture one failing session, identify the exact log line, change the matching capability or client timeout, then rerun the same failure path. Logs may contain app identifiers, device names, UDIDs, paths, and account data, so mask those values before sharing output outside the team.
Related: How to debug Appium session logs
Related: How to configure waits in Appium tests
Related: How to start the Appium server
$ appium --address 127.0.0.1 --port 4723 --log appium-timeout.log --log-level info:debug --log-no-colors --log-timestamp [Appium] Welcome to Appium v3.5.0 [Appium] Appium REST http interface listener started on http://127.0.0.1:4723
The info:debug log level keeps the terminal readable while preserving request, driver, and timeout details in appium-timeout.log. Start the server from the same shell and APPIUM_HOME used by the failing test.
Related: How to start the Appium server
Related: How to use APPIUM_HOME for Appium extensions
$ curl --silent http://127.0.0.1:4723/status
{"value":{"ready":true,"message":"The server is ready to accept new connections","build":{"version":"3.5.0"}}}
If the status endpoint does not answer, fix the server process or listener URL before changing session capabilities.
$ pytest tests/test_login.py::test_login -q E selenium.common.exceptions.InvalidSessionIdException: E Message: A session is either terminated or not started
Keep the reproduction to one session when possible. Several failed sessions in one log make it harder to match the timeout line to the command that caused it.
$ cat appium-timeout.log [Driver] Shutting down because we waited 60 seconds for a command [AppiumDriver] Ending session, cause was 'New Command Timeout of 60 seconds expired. Try customizing the timeout using the 'newCommandTimeout' desired capability' [HTTP] <-- GET /session/11111111-2222-3333-4444-555555555555/source 404
This message means Appium closed a session because no new command arrived before appium:newCommandTimeout expired. A platform startup timeout, WebDriverAgent timeout, ADB timeout, or client HTTP timeout needs a different fix.
Related: How to debug Appium session logs
Tool: Application Log Pattern Analyzer
{
"capabilities": {
"alwaysMatch": {
"platformName": "Android",
"appium:automationName": "UiAutomator2",
"appium:deviceName": "Android Emulator",
"appium:appPackage": "com.example.mobile",
"appium:appActivity": ".MainActivity",
"appium:newCommandTimeout": 180
}
}
}
The value is in seconds. Use a bounded value such as 180 or 300 for real test suites, and use 0 only while actively debugging an idle-session problem.
$ curl --silent --request POST http://127.0.0.1:4723/session --header "Content-Type: application/json" --data @session.json
{"value":{"capabilities":{"platformName":"Android","automationName":"UiAutomator2","newCommandTimeout":180},"sessionId":"11111111-2222-3333-4444-555555555555"}}
Change the project capability file or test-runner configuration after the focused request succeeds. Do not leave a temporary curl payload as the only place where the fix exists.
$ curl --silent http://127.0.0.1:4723/session/11111111-2222-3333-4444-555555555555/source
{"value":"<hierarchy>##### snipped #####</hierarchy>"}
A successful response after the same idle interval proves the server idle timeout was the failing layer. If the session still disappears, confirm that the client is talking to the new session ID and the same Appium server.
Android app launch messages that mention the expected activity or appWaitDuration should be handled with Android launch capabilities such as appium:appWaitDuration. WebDriverAgent or simulator startup messages should be handled in the XCUITest capability or environment named by the log. Client-side read or request timeouts belong in the Appium client configuration, not in appium:newCommandTimeout.
$ pytest tests/test_login.py::test_login -q . 1 passed in 21.08s
The original timeout message should disappear without masking unrelated startup, locator, or app-state failures. If a new Appium error appears, keep the log and troubleshoot the new layer separately.
$ rm session.json
Keep the masked appium-timeout.log with the test report or issue ticket. Delete only temporary payloads that contain copied app identifiers or device details.