{"record":{"id":"cf2a54ce500eb606","repo":"google/ExoPlayer","slug":"invalid-uri-scheme-or-authority","errorCode":null,"errorMessage":"Invalid URI scheme or authority.","messagePattern":"Invalid URI scheme or authority\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaServerSideAdInsertionUriBuilder.java","lineNumber":336,"sourceCode":"\n  /** Returns the opaque adsId for this stream. */\n  /* package */ static String getAdsId(Uri uri) {\n    return checkNotNull(uri.getQueryParameter(ADS_ID));\n  }\n\n  /** Returns the video load timeout in milliseconds. */\n  /* package */ static int getLoadVideoTimeoutMs(Uri uri) {\n    @Nullable String adsLoaderTimeoutUs = uri.getQueryParameter(LOAD_VIDEO_TIMEOUT_MS);\n    return TextUtils.isEmpty(adsLoaderTimeoutUs)\n        ? DEFAULT_LOAD_VIDEO_TIMEOUT_MS\n        : Integer.parseInt(adsLoaderTimeoutUs);\n  }\n\n  /** Returns the corresponding {@link StreamRequest}. */\n  @SuppressWarnings(\"nullness\") // Required for making nullness test pass for library_with_ima_sdk.\n  /* package */ static StreamRequest createStreamRequest(Uri uri) {\n    if (!C.SSAI_SCHEME.equals(uri.getScheme()) || !IMA_AUTHORITY.equals(uri.getAuthority())) {\n      throw new IllegalArgumentException(\"Invalid URI scheme or authority.\");\n    }\n    StreamRequest streamRequest;\n    // Required params.\n    @Nullable String assetKey = uri.getQueryParameter(ASSET_KEY);\n    @Nullable String apiKey = uri.getQueryParameter(API_KEY);\n    @Nullable String contentSourceId = uri.getQueryParameter(CONTENT_SOURCE_ID);\n    @Nullable String videoId = uri.getQueryParameter(VIDEO_ID);\n    if (!TextUtils.isEmpty(assetKey)) {\n      streamRequest = ImaSdkFactory.getInstance().createLiveStreamRequest(assetKey, apiKey);\n    } else {\n      streamRequest =\n          ImaSdkFactory.getInstance()\n              .createVodStreamRequest(checkNotNull(contentSourceId), checkNotNull(videoId), apiKey);\n    }\n    int format = Integer.parseInt(uri.getQueryParameter(FORMAT));\n    if (format == C.CONTENT_TYPE_DASH) {\n      streamRequest.setFormat(StreamFormat.DASH);\n    } else if (format == C.CONTENT_TYPE_HLS) {","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaServerSideAdInsertionUriBuilder.java#L318-L354","documentation":"Thrown by ImaServerSideAdInsertionUriBuilder.createStreamRequest when the URI passed in does not have both the expected SSAI scheme (imasky via C.SSAI_SCHEME) and the IMA authority. These URIs are synthetic identifiers that only exist to carry DAI stream parameters from your app into the ImaServerSideAdInsertionMediaSource; anything else reaching this method is a programming error.","triggerScenarios":"Calling createStreamRequest with a URI whose getScheme() != C.SSAI_SCHEME or getAuthority() != IMA_AUTHORITY — typically because the URI was hand-concatenated (e.g. \"imasky://\" misspelled), parsed from a string that lost its scheme, or an unrelated content URI was routed to the SSAI media source.","commonSituations":"Building the SSAI URI manually with String concatenation instead of ImaServerSideAdInsertionUriBuilder; Uri.parse on a malformed string returning a Uri with null scheme/authority; a custom MediaSourceFactory delegating all items to the SSAI source without a scheme check.","solutions":["Always construct the URI with ImaServerSideAdInsertionUriBuilder.build() rather than string concatenation — it emits the correct scheme/authority by construction.","If you must inspect URIs, gate routing on C.SSAI_SCHEME.equals(uri.getScheme()) && IMA_AUTHORITY.equals(uri.getAuthority()) before passing to the SSAI source.","Log the offending URI at the point of failure to find which code path produced the malformed value."],"exampleFix":"// before\nUri uri = Uri.parse(\"imsky://ima/?asset_key=...\"); // typo'd scheme -> IllegalArgumentException\n\n// after\nUri uri = new ImaServerSideAdInsertionUriBuilder()\n    .setAssetKey(\"...\")\n    .setFormat(C.CONTENT_TYPE_HLS)\n    .build();","handlingStrategy":"type-guard","validationCode":"boolean isSsaiUri(Uri uri) {\n  return C.SSAI_SCHEME.equals(uri.getScheme())\n      && ImaServerSideAdInsertionUriBuilder.IMA_AUTHORITY.equals(uri.getAuthority());\n}","typeGuard":"static boolean isImaSsaiUri(@Nullable Uri uri) {\n  return uri != null\n      && C.SSAI_SCHEME.equals(uri.getScheme())\n      && \"ima\".equals(uri.getAuthority());\n}","tryCatchPattern":"catch (IllegalArgumentException e) { if (\"Invalid URI scheme or authority.\".equals(e.getMessage())) { rejectItem(); } else throw e; }","preventionTips":["Always construct SSAI URIs via ImaServerSideAdInsertionUriBuilder — never string concatenation.","Route media items by scheme/authority before handing them to the SSAI MediaSource."],"tags":["ima","ssai","uri","validation"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}