signalapp/Signal-Server · error · JsonParseException

Could not parse string as a base64-encoded value

Error message

Could not parse string as a base64-encoded value

What it means

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.

Solutions

  1. Ensure the JSON field is a valid standard-Base64 string before submitting
  2. Confirm the client encodes the backup auth credential bytes with Base64.getEncoder().encodeToString(...)
  3. Check the payload is not empty, truncated, or containing whitespace/URL-safe Base64 characters
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at service/src/main/java/org/whispersystems/textsecuregcm/util/BackupAuthCredentialAdapter.java:44 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09). Data as JSON: /api/errors/b1f334872b5f362d. Report an issue: GitHub.

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/util/BackupAuthCredentialAdapter.java:44

  private static final Counter INVALID_BASE64_COUNTER =
      Metrics.counter(MetricsUtil.name(BackupAuthCredentialAdapter.class, "invalidBase64"));

  private static final Counter INVALID_BYTES_COUNTER =
      Metrics.counter(MetricsUtil.name(BackupAuthCredentialAdapter.class, "invalidBackupAuthObject"));

  abstract static class GenericDeserializer<T> extends JsonDeserializer<T> {

    abstract T deserialize(final byte[] bytes) throws InvalidInputException;

    @Override
    public T deserialize(final JsonParser parser, final DeserializationContext deserializationContext)
        throws IOException {
      final byte[] bytes;
      try {
        bytes = Base64.getDecoder().decode(parser.getValueAsString());
      } catch (final IllegalArgumentException e) {
        INVALID_BASE64_COUNTER.increment();
        throw new JsonParseException(parser, "Could not parse string as a base64-encoded value", e);
      }
      try {
        return deserialize(bytes);
      } catch (InvalidInputException e) {
        INVALID_BYTES_COUNTER.increment();
        throw new JsonParseException(parser, "Could not interpret bytes as a BackupAuth object");
      }
    }
  }

  static class GenericSerializer<T extends ByteArray> extends JsonSerializer<T> {

    @Override
    public void serialize(final T t, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
        throws IOException {
      jsonGenerator.writeString(Base64.getEncoder().encodeToString(t.serialize()));
    }
  }

View on GitHub (pinned to 100ab61c82)