From dbd9b9ff9ebc4e51aeefd2631f86daf0ca32228c Mon Sep 17 00:00:00 2001 From: Andrey Kolkov Date: Wed, 22 Jul 2026 11:21:53 +0400 Subject: [PATCH] fix(backups): request S3 checksum only when required for barman-cloud The barman-cloud plugin's sidecar uploads via boto3. Since botocore ~1.36 (early 2025) the default RequestChecksumCalculation is when_supported, which attaches a flexible checksum to every PutObject. Non-AWS S3-compatible backends (Ceph RADOS Gateway, some MinIO / Cloudflare R2 builds) reject the accompanying header with "InvalidArgument: x-amz-content-sha256 must be UNSIGNED-PAYLOAD, STREAMING-AWS4-HMAC-SHA256-PAYLOAD or a valid sha256 value", so every backup/WAL-archive upload fails against them. Pin the sidecar to when_required via the ObjectStore's spec.instanceSidecarConfiguration.env (botocore honors the AWS_REQUEST_CHECKSUM_CALCULATION env var) on both the keycloak system DB and the postgres app (backup + recovery ObjectStores). when_required is also accepted by AWS S3 on a plain PutObject, so it is a safe default everywhere. This mirrors the etcd-operator fix (cozystack/etcd-operator#342, released in v0.5.3), which applied the same WhenRequired policy to its aws-sdk-go-v2 S3 client for the same Ceph RGW backend. Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: Andrey Kolkov (cherry picked from commit 0c586b9d72d3c3d05c25d4ed74a5039482472589) --- packages/apps/postgres/templates/db.yaml | 14 ++++++++++++++ packages/system/keycloak/templates/db.yaml | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/packages/apps/postgres/templates/db.yaml b/packages/apps/postgres/templates/db.yaml index a59b137d1..b9ad00c30 100644 --- a/packages/apps/postgres/templates/db.yaml +++ b/packages/apps/postgres/templates/db.yaml @@ -262,6 +262,15 @@ spec: {{- if .Values.backup.retentionPolicy }} retentionPolicy: {{ .Values.backup.retentionPolicy | quote }} {{- end }} + # Ceph RGW and other non-AWS S3-compatible backends reject botocore's default + # flexible request checksum (the x-amz-content-sha256 that barman-cloud's + # boto3 sends on every upload) with "InvalidArgument: x-amz-content-sha256 + # must be UNSIGNED-PAYLOAD, ...". Compute a checksum only when the operation + # requires one; AWS S3 accepts this too, so it is a safe default everywhere. + instanceSidecarConfiguration: + env: + - name: AWS_REQUEST_CHECKSUM_CALCULATION + value: when_required configuration: destinationPath: {{ $destinationPath }} endpointURL: {{ $endpointURL }} @@ -288,6 +297,11 @@ kind: ObjectStore metadata: name: {{ .Release.Name }}-recovery spec: + # Same non-AWS S3 request-checksum workaround as the backup ObjectStore above. + instanceSidecarConfiguration: + env: + - name: AWS_REQUEST_CHECKSUM_CALCULATION + value: when_required configuration: destinationPath: {{ $destinationPath }} endpointURL: {{ $endpointURL }} diff --git a/packages/system/keycloak/templates/db.yaml b/packages/system/keycloak/templates/db.yaml index 8b8b32823..d33766583 100644 --- a/packages/system/keycloak/templates/db.yaml +++ b/packages/system/keycloak/templates/db.yaml @@ -51,6 +51,15 @@ spec: {{- if .Values.backup.retentionPolicy }} retentionPolicy: {{ .Values.backup.retentionPolicy | quote }} {{- end }} + # Ceph RGW and other non-AWS S3-compatible backends reject botocore's default + # flexible request checksum (the x-amz-content-sha256 that barman-cloud's + # boto3 sends on every upload) with "InvalidArgument: x-amz-content-sha256 + # must be UNSIGNED-PAYLOAD, ...". Compute a checksum only when the operation + # requires one; AWS S3 accepts this too, so it is a safe default everywhere. + instanceSidecarConfiguration: + env: + - name: AWS_REQUEST_CHECKSUM_CALCULATION + value: when_required configuration: destinationPath: {{ .Values.backup.destinationPath | quote }} {{- with .Values.backup.endpointURL }}