{"record":{"id":"add8d5d8c07dce0a","repo":"google/ExoPlayer","slug":"errormessage-errorcode-errorcode","errorCode":null,"errorMessage":"${errorMessage} [errorCode: ${errorCode}]","messagePattern":"(.+?) \\[errorCode: (.+?)\\]","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaServerSideAdInsertionMediaSource.java","lineNumber":1065,"sourceCode":"            (streamUri, subtitles) -> {\n              contentUri = Uri.parse(streamUri);\n              conditionVariable.open();\n            });\n        if (adErrorListener != null) {\n          adsLoader.addAdErrorListener(adErrorListener);\n        }\n        adsLoader.addAdsLoadedListener(this);\n        adsLoader.addAdErrorListener(this);\n        adsLoader.requestStream(request);\n        while (contentUri == null && !cancelled && !error) {\n          try {\n            conditionVariable.block();\n          } catch (InterruptedException e) {\n            /* Do nothing. */\n          }\n        }\n        if (error && contentUri == null) {\n          throw new IOException(errorMessage + \" [errorCode: \" + errorCode + \"]\");\n        }\n      } finally {\n        adsLoader.removeAdsLoadedListener(this);\n        adsLoader.removeAdErrorListener(this);\n        if (adErrorListener != null) {\n          adsLoader.removeAdErrorListener(adErrorListener);\n        }\n      }\n    }\n\n    @Override\n    public void cancelLoad() {\n      cancelled = true;\n    }\n\n    // AdsLoader.AdsLoadedListener implementation.\n\n    @MainThread","sourceCodeStart":1047,"sourceCodeEnd":1083,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaServerSideAdInsertionMediaSource.java#L1047-L1083","documentation":"Thrown by the stream-resolution loader in ImaServerSideAdInsertionMediaSource when the IMA SDK reported a stream request error and no content URI was obtained before the load was cancelled. The message concatenates the IMA error message and IMA error code, so the underlying cause comes straight from the IMA stream request API.","triggerScenarios":"ImaServerSideAdInsertionMediaSource requests a DAI stream (adsLoader.requestStream(request)); onAdsLoadError sets error=true with errorMessage/errorCode from IMA's AdError; the blocking wait loop exits and, because contentUri is still null, this IOException propagates out of the Loader. Typical triggers: invalid asset key / content source ID, DRM or network failures reaching the DAI backend, malformed stream request parameters built by ImaServerSideAdInsertionUriBuilder.","commonSituations":"Typo'd or expired asset_key/cmsId+videoId in the SSAI URI; a device without network access or behind a firewall blocking DAI endpoints; an IMA SDK/DAI backend version mismatch; test streams that have been deprovisioned by Google.","solutions":["Inspect the errorMessage/errorCode in the thrown IOException — they are IMA's own diagnostics (e.g. stream download failure vs invalid asset key) and identify the exact problem.","Validate the SSAI URI parameters: correct assetKey (live) or contentSourceId+videoId (VOD), and a supported FORMAT (dash/hls); build it with ImaServerSideAdInsertionUriBuilder to avoid mistakes.","Check network reachability of the IMA/DAI endpoints from the device and retry with a known-good public DAI test stream (Google provides reference asset keys).","Update the IMA extension and IMA SDK to the latest matching versions, then re-test — older combinations have known stream-request failures."],"exampleFix":"// before\nString uri = \"imasky://example.com?asset_key=WRONG&format=0\"; // errorCode surfaced in IOException\n\n// after\nString uri = new ImaServerSideAdInsertionUriBuilder()\n    .setAssetKey(\"your-asset-key\")\n    .setFormat(C.CONTENT_TYPE_DASH)\n    .build()\n    .toString();","handlingStrategy":"try-catch","validationCode":"// Validate SSAI URI params before playback:\n@Nullable String assetKey = uri.getQueryParameter(\"asset_key\");\n@Nullable String vid = uri.getQueryParameter(\"v\");\nif ((assetKey == null) && (uri.getQueryParameter(\"cmsid\") == null || vid == null)) {\n  Log.e(TAG, \"SSAI URI missing required params\");\n}","typeGuard":null,"tryCatchPattern":"// in Loadable catch / Player.Listener:\ncatch (IOException e) { // message contains IMA errorMessage + errorCode\n  if (e.getMessage() != null && e.getMessage().contains(\"errorCode\")) showAdStreamError(e.getMessage());\n}","preventionTips":["Build SSAI URIs only with ImaServerSideAdInsertionUriBuilder.","Keep one validated DAI test stream in your test suite to distinguish config vs network failures.","Surface the embedded IMA errorCode to your telemetry."],"tags":["ima","ssai","dai","network","stream-request"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}