{"record":{"id":"fb3fcd54c415125a","repo":"signalapp/Signal-Server","slug":"username-or-password-were-blank","errorCode":null,"errorMessage":"Username or password were blank","messagePattern":"Username or password were blank","errorType":"http","errorClass":"InvalidAuthorizationHeaderException","httpStatus":401,"severity":"error","filePath":"service/src/main/java/org/whispersystems/textsecuregcm/auth/BasicAuthorizationHeader.java","lineNumber":74,"sourceCode":"        throw new InvalidAuthorizationHeaderException(\"Badly-formatted credentials: \" + credentials);\n      }\n\n      final String usernameComponent = credentials.substring(0, credentialSeparatorIndex);\n\n      final String username;\n      final byte deviceId;\n      {\n        final Pair<String, Byte> identifierAndDeviceId =\n            AccountAuthenticator.getIdentifierAndDeviceId(usernameComponent);\n\n        username = identifierAndDeviceId.first();\n        deviceId = identifierAndDeviceId.second();\n      }\n\n      final String password = credentials.substring(credentialSeparatorIndex + 1);\n\n      if (StringUtils.isAnyBlank(username, password)) {\n        throw new InvalidAuthorizationHeaderException(\"Username or password were blank\");\n      }\n\n      return new BasicAuthorizationHeader(username, deviceId, password);\n    } catch (final IllegalArgumentException | IndexOutOfBoundsException e) {\n      throw new InvalidAuthorizationHeaderException(e);\n    }\n  }\n\n  public String getUsername() {\n    return username;\n  }\n\n  public long getDeviceId() {\n    return deviceId;\n  }\n\n  public String getPassword() {\n    return password;","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/service/src/main/java/org/whispersystems/textsecuregcm/auth/BasicAuthorizationHeader.java#L56-L92","documentation":"fromString throws InvalidAuthorizationHeaderException(\"Username or password were blank\") when either the parsed username component or the password substring is blank, even though the colon separator existed.","triggerScenarios":"base64(\":password\") (blank username), base64(\"username:\") (blank password), or base64(\"  :  \").","commonSituations":"Config with a set username but missing password (or vice versa); device ID parsing producing an empty username; partial credentials copied from a store.","solutions":["Provide both a non-blank username (account identifier, optionally with .deviceId) and non-blank password","Validate credentials client-side before encoding","Re-fetch or regenerate the account's auth credentials if one part is missing"],"exampleFix":"// before\nString creds = base64(\":\" + password);\n// after\nString creds = base64(accountNumber + \".1:\" + password);","handlingStrategy":"validation","validationCode":"String[] parts = decoded.split(\":\", 2);\nif (parts.length != 2 || parts[0].isBlank() || parts[1].isBlank()) throw new IllegalArgumentException(\"username and password must both be non-blank\");","typeGuard":null,"tryCatchPattern":"try { BasicAuthorizationHeader.fromString(header); } catch (InvalidAuthorizationHeaderException e) { throw new NotAuthorizedException(\"Basic\"); }","preventionTips":["Validate both credential fields at config load time","Include the account identifier (E.164, optionally .deviceId) as the username"],"tags":["basic-auth","blank-value","credentials"],"backgroundTag":"missing-credentials","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"}