{"record":{"id":"731e68722698cc9b","repo":"signalapp/Signal-Server","slug":"invalid-authorization-header","errorCode":null,"errorMessage":"Invalid authorization header: ","messagePattern":"Invalid authorization header: ","errorType":"http","errorClass":"InvalidAuthorizationHeaderException","httpStatus":401,"severity":"error","filePath":"service/src/main/java/org/whispersystems/textsecuregcm/auth/BasicAuthorizationHeader.java","lineNumber":32,"sourceCode":"  private final byte deviceId;\n  private final String password;\n\n  private BasicAuthorizationHeader(final String username, final byte deviceId, final String password) {\n    this.username = username;\n    this.deviceId = deviceId;\n    this.password = password;\n  }\n\n  public static BasicAuthorizationHeader fromString(final String header) throws InvalidAuthorizationHeaderException {\n    try {\n      if (StringUtils.isBlank(header)) {\n        throw new InvalidAuthorizationHeaderException(\"Blank header\");\n      }\n\n      final int spaceIndex = header.indexOf(' ');\n\n      if (spaceIndex == -1) {\n        throw new InvalidAuthorizationHeaderException(\"Invalid authorization header: \" + header);\n      }\n\n      final String authorizationType = header.substring(0, spaceIndex);\n\n      if (!\"Basic\".equals(authorizationType)) {\n        throw new InvalidAuthorizationHeaderException(\"Unsupported authorization method: \" + authorizationType);\n      }\n\n      final String credentials;\n\n      try {\n        credentials = new String(Base64.getDecoder().decode(header.substring(spaceIndex + 1)));\n      } catch (final IndexOutOfBoundsException e) {\n        throw new InvalidAuthorizationHeaderException(\"Missing credentials\");\n      }\n\n      if (StringUtils.isEmpty(credentials)) {\n        throw new InvalidAuthorizationHeaderException(\"Bad decoded value: \" + credentials);","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/service/src/main/java/org/whispersystems/textsecuregcm/auth/BasicAuthorizationHeader.java#L14-L50","documentation":"fromString throws InvalidAuthorizationHeaderException(\"Invalid authorization header: <header>\") when the header contains no space, so it cannot be split into an authorization type and credentials. Basic auth headers must be of the form \"Basic <base64>\".","triggerScenarios":"Header value like \"Basic\" alone, a raw base64 blob without the scheme, or a token pasted without the 'Basic ' prefix.","commonSituations":"Clients concatenating scheme and credentials without a space; missing the scheme entirely; some proxies rewriting the header.","solutions":["Send the header as 'Basic ' + base64(username:password) including the space","If using a token, use the appropriate Bearer auth provider instead","Log/inspect the raw Authorization header to spot missing scheme"],"exampleFix":"// before\nrequest.setHeader(\"Authorization\", base64(user + \":\" + pass));\n// after\nrequest.setHeader(\"Authorization\", \"Basic \" + base64(user + \":\" + pass));","handlingStrategy":"validation","validationCode":"if (!header.contains(\" \")) throw new IllegalArgumentException(\"Authorization header must be '<scheme> <credentials>'\");","typeGuard":null,"tryCatchPattern":"try { BasicAuthorizationHeader.fromString(header); } catch (InvalidAuthorizationHeaderException e) { throw new NotAuthorizedException(\"Basic\"); }","preventionTips":["Build headers as \"Basic \" + encoded with an explicit space","Use a client auth interceptor that formats the header once, correctly"],"tags":["http-header","basic-auth","malformed"],"backgroundTag":"invalid-argument-format","analyzedSha":"100ab61c82627582c867d19e1c0561ba2781e927","analyzedAt":"2026-09-09T13:29:47.883Z","contentChangedAt":"2026-09-09T13:29:47.883Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}