{"record":{"id":"f5660d0f1c8b14e9","repo":"apache/iceberg","slug":"payload-signing-not-supported","errorCode":null,"errorMessage":"Payload signing not supported","messagePattern":"Payload signing not supported","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"aws/src/main/java/org/apache/iceberg/aws/s3/signer/S3V4RestSignerClient.java","lineNumber":387,"sourceCode":"      Map<String, List<String>> signedAndUnsignedHeaders,\n      SdkHttpFullRequest.Builder mutableRequest) {\n    Map<String, List<String>> headers = Maps.newHashMap(signedAndUnsignedHeaders);\n    // we need to remove the Cache-Control header that is being sent by the server\n    headers.remove(CACHE_CONTROL);\n\n    // we need to overwrite whatever headers the server signed/unsigned with the ones from the\n    // original request and then put all headers back to the request\n    headers.putAll(mutableRequest.headers());\n    headers.forEach(mutableRequest::putHeader);\n  }\n\n  private boolean canBeCached(Map<String, String> responseHeaders) {\n    return CACHE_CONTROL_PRIVATE.equals(responseHeaders.get(CACHE_CONTROL));\n  }\n\n  private void checkSignerParams(AwsS3V4SignerParams signerParams) {\n    if (signerParams.enablePayloadSigning()) {\n      throw new UnsupportedOperationException(\"Payload signing not supported\");\n    }\n\n    if (signerParams.enableChunkedEncoding()) {\n      throw new UnsupportedOperationException(\"Chunked encoding not supported\");\n    }\n  }\n\n  @Value.Immutable\n  interface Key {\n    String method();\n\n    String region();\n\n    String uri();\n\n    static Key from(RemoteSignRequest request) {\n      return ImmutableKey.builder()\n          .method(request.method())","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/aws/src/main/java/org/apache/iceberg/aws/s3/signer/S3V4RestSignerClient.java#L369-L405","documentation":"checkSignerParams() rejects AwsS3V4SignerParams with enablePayloadSigning()=true. The remote REST signer signs requests without transmitting payloads to the signer and requires unsigned payloads; payload signing is explicitly unsupported.","triggerScenarios":"The AWS SDK produces signer params with payload signing enabled (e.g. certain request types or SDK defaults) while using the remote S3 signer via processRequestPayload.","commonSituations":"S3 Access Grants flows where the SDK enables payload signing by default; clients not setting the Iceberg property to disable payload signing; certain operations (e.g. PutObject with checksums) forcing signed payloads.","solutions":["Enable remote signing without payload signing (Iceberg handles the s3.remote-signing-enabled wiring automatically).","Check which operation triggered signed payloads and whether it is compatible with remote signing.","Fall back to standard AWS credentials (non-remote signing) if payload signing is mandatory for your workload.","Upgrade Iceberg/SDK versions where payload-signing defaults are handled."],"exampleFix":"// before\n// remote signer with payload signing enabled by SDK default\nS3Client.builder().credentialsProvider(accessGrantsProvider).build();\n// after\n// let Iceberg configure the signer with unsigned payload\nS3FileIO io = new S3FileIO(props); // remoteSigningEnabled handles params","handlingStrategy":"validation","validationCode":"// Java\nif (signerParams.enablePayloadSigning()) {\n  throw new IllegalStateException(\"Remote S3 signer requires payload signing disabled\");\n}","typeGuard":null,"tryCatchPattern":"// Java\ntry {\n  io.newOutputFile(loc).createOrOverwrite();\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().equals(\"Payload signing not supported\")) {\n    LOG.error(\"Disable payload signing or fall back to standard credential signing\");\n  }\n}","preventionTips":["Do not force payload signing in SDK config when remote signing is enabled","Test write operations (PutObject) under remote signing before production","Fall back to normal AWS credentials for workloads that mandate signed payloads"],"tags":["s3","signer","payload-signing","unsupported"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}