Introduction

Kubernetes Secrets are simple conceptually, but the data field requires properly base64-encoded values. Many failures come from tiny mistakes: using echo without suppressing the newline, double-encoding an already encoded value, or mixing data and stringData assumptions. The result is either an apply-time base64 error or a Secret that loads successfully but contains the wrong decoded content.

Symptoms

  • kubectl apply fails with illegal base64 data
  • The Secret exists, but the application reads malformed values
  • Operators see the encoded text itself where the decoded secret should appear
  • The same Secret works in one shell or OS and breaks in another

Common Causes

  • A value in data is not valid base64
  • echo added a trailing newline before encoding
  • The value was encoded twice
  • data and stringData usage was mixed without understanding how Kubernetes handles them

Step-by-Step Fix

  1. 1.**Use stringData when you want Kubernetes to do the encoding**
  2. 2.This is the safest path for many hand-authored manifests.
yaml
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-secret
stringData:
  password: my-password
  1. 1.**If using data, encode without a newline**
  2. 2.Trailing newlines are a common source of confusing mismatches.
bash
echo -n "my-password" | base64
  1. 1.Decode and verify the stored value
  2. 2.Do not assume the encoded string is correct just because the Secret applied successfully.
bash
kubectl get secret my-secret -o jsonpath='{.data.password}' | base64 -d
  1. 1.**Avoid mixing data and stringData for the same key casually**
  2. 2.Keep the representation simple and explicit so future edits do not create hidden overrides.

Prevention

  • Prefer stringData for human-authored manifests
  • Use echo -n or an equivalent newline-safe encoder when generating base64 manually
  • Decode and inspect critical secret values before rollout
  • Keep secret generation automated and consistent across platforms