signalapp/Signal-Server · error · BadRequestException

Invalid create call link credential request

Error message

Invalid create call link credential request

What it means

CallLinkController.getCreateAuth wraps the client-supplied create-call-link-credential-request bytes into CreateCallLinkCredentialRequest; if parsing raises InvalidInputException the endpoint returns 400 'Invalid create call link credential request'.

Solutions

  1. Regenerate the CreateCallLinkCredentialRequest client-side with a current, matching library version
  2. Ensure the raw serialized bytes (correct encoding) are placed in the request field unmodified
  3. Verify client and server use compatible GenericServerSecretParams / version (v101 flag)

Example fix

// before
request.createCallLinkCredentialRequest = someBase64String.getBytes();
// after
byte[] bytes = CreateCallLinkCredentialRequestJsonAdapter
    .serialize(new CreateCallLinkCredentialRequest(randomToken));
request.createCallLinkCredentialRequest = bytes;
Defensive patterns

Strategy: try-catch

Validate before calling

try { new CreateCallLinkCredentialRequest(bytes); } catch (InvalidInputException e) { rebuildCredentialRequest(); }

Try / catch

try { callLinkAuth(request); } catch (WebApplicationException e) { if (e.getResponse().getStatus() == 400) regenerateCredentialRequestAndRetry(); }

Prevention

When it happens

Trigger: POST to /v1/call-link/auth with a request body whose createCallLinkCredentialRequest field holds malformed or invalid byte content.

Common situations: Client built the credential request with the wrong library version or wrong server secret params; protobuf bytes corrupted/truncated in transit or mis-serialized (e.g. base64 vs raw mixup).

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/controllers/CallLinkController.java:73

  @ApiResponse(responseCode = "401", description = "Account authentication check failed.")
  @ApiResponse(responseCode = "422", description = "Invalid request format.")
  @ApiResponse(responseCode = "429", description = "Ratelimited.")
  public CreateCallLinkCredential getCreateAuth(
      final @Auth AuthenticatedDevice auth,
      final @NotNull @Valid GetCreateCallLinkCredentialsRequest request,
      @Parameter(description = "Whether to use libsignal v0.101.0+ secret params")
      final @QueryParam("v101") boolean v101
  ) throws RateLimitExceededException {

    rateLimiters.getCreateCallLinkLimiter().validate(auth.accountIdentifier());

    final Instant truncatedDayTimestamp = Instant.now().truncatedTo(ChronoUnit.DAYS);

    CreateCallLinkCredentialRequest createCallLinkCredentialRequest;
    try {
      createCallLinkCredentialRequest = new CreateCallLinkCredentialRequest(request.createCallLinkCredentialRequest());
    } catch (InvalidInputException e) {
      throw new BadRequestException("Invalid create call link credential request", e);
    }

    return new CreateCallLinkCredential(
        createCallLinkCredentialRequest.issueCredential(new ServiceId.Aci(auth.accountIdentifier()), truncatedDayTimestamp, v101 ? genericServerSecretParams : genericServerSecretParamsPreV101).serialize(),
        truncatedDayTimestamp.getEpochSecond()
    );
  }
}

View on GitHub (pinned to 100ab61c82)