{"record":{"id":"b1f334872b5f362d","repo":"signalapp/Signal-Server","slug":"could-not-parse-string-as-a-base64-encoded-value","errorCode":null,"errorMessage":"Could not parse string as a base64-encoded value","messagePattern":"Could not parse string as a base64-encoded value","errorType":"validation","errorClass":"JsonParseException","httpStatus":400,"severity":"error","filePath":"service/src/main/java/org/whispersystems/textsecuregcm/util/BackupAuthCredentialAdapter.java","lineNumber":44,"sourceCode":"  private static final Counter INVALID_BASE64_COUNTER =\n      Metrics.counter(MetricsUtil.name(BackupAuthCredentialAdapter.class, \"invalidBase64\"));\n\n  private static final Counter INVALID_BYTES_COUNTER =\n      Metrics.counter(MetricsUtil.name(BackupAuthCredentialAdapter.class, \"invalidBackupAuthObject\"));\n\n  abstract static class GenericDeserializer<T> extends JsonDeserializer<T> {\n\n    abstract T deserialize(final byte[] bytes) throws InvalidInputException;\n\n    @Override\n    public T deserialize(final JsonParser parser, final DeserializationContext deserializationContext)\n        throws IOException {\n      final byte[] bytes;\n      try {\n        bytes = Base64.getDecoder().decode(parser.getValueAsString());\n      } catch (final IllegalArgumentException e) {\n        INVALID_BASE64_COUNTER.increment();\n        throw new JsonParseException(parser, \"Could not parse string as a base64-encoded value\", e);\n      }\n      try {\n        return deserialize(bytes);\n      } catch (InvalidInputException e) {\n        INVALID_BYTES_COUNTER.increment();\n        throw new JsonParseException(parser, \"Could not interpret bytes as a BackupAuth object\");\n      }\n    }\n  }\n\n  static class GenericSerializer<T extends ByteArray> extends JsonSerializer<T> {\n\n    @Override\n    public void serialize(final T t, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)\n        throws IOException {\n      jsonGenerator.writeString(Base64.getEncoder().encodeToString(t.serialize()));\n    }\n  }","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/service/src/main/java/org/whispersystems/textsecuregcm/util/BackupAuthCredentialAdapter.java#L26-L62","documentation":"Thrown by BackupAuthCredentialAdapter's GenericDeserializer when the JSON string value cannot be decoded as Base64. The IllegalArgumentException from Base64.getDecoder().decode is caught, the INVALID_BASE64_COUNTER metric is incremented, and a JsonParseException is raised, so the field fails Jackson deserialization. The faulting input is the malformed Base64 string supplied for a BackupAuth credential field.","triggerScenarios":"Thrown at service/src/main/java/org/whispersystems/textsecuregcm/util/BackupAuthCredentialAdapter.java:44 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Ensure the JSON field is a valid standard-Base64 string before submitting","Confirm the client encodes the backup auth credential bytes with Base64.getEncoder().encodeToString(...)","Check the payload is not empty, truncated, or containing whitespace/URL-safe Base64 characters"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}