Helm Sprig print quote default Functions
Helm Sprig print function concatenates without spaces, quote wraps in double quotes, default provides fallback values. Template examples and patterns.
π‘ Quick Answer: `print` concatenates values without separators, `quote` wraps strings in double quotes for YAML safety, and `default` provides fallback values when a variable is empty or undefined. These three Sprig functions handle 90% of Helm string formatting needs.
The Problem
Helm templates generate YAML, and YAML is whitespace-sensitive and type-sensitive. Common issues include:
- Values with special characters breaking YAML parsing
- Undefined values causing template rendering failures
- Need to format strings without the spaces that `cat` inserts
flowchart LR
INPUT["Template Value"] --> PRINT["print<br/>No separators"]
INPUT --> QUOTE["quote<br/>YAML-safe strings"]
INPUT --> DEFAULT["default<br/>Fallback values"]
PRINT --> YAML["Valid YAML Output"]
QUOTE --> YAML
DEFAULT --> YAMLThe Solution
The `print` Function
`print` concatenates values without spaces (unlike `cat` which adds spaces):
# cat vs print comparison
{{ cat "hello" "world" }} # β "hello world" (space between)
{{ print "hello" "world" }} # β "helloworld" (no space)
# Build resource names
{{ print .Release.Name "-" .Chart.Name }}
# β "myrelease-mychart"
# Construct image references
image: {{ print .Values.image.registry "/" .Values.image.repository ":" .Values.image.tag }}
# β "registry.example.com/myapp:v1.2.3"`printf` β Formatted Output
# printf uses Go fmt verbs
{{ printf "%s-%s" .Release.Name .Chart.Name }}
# β "myrelease-mychart"
# With numbers
{{ printf "port-%d" .Values.service.port }}
# β "port-8080"
# Padding
{{ printf "%-20s %s" .Values.name .Values.version }}
# β "myapp v1.2.3"
# Common Kubernetes pattern: generate annotation values
annotations:
app.kubernetes.io/version: {{ printf "%s+build.%s" .Chart.AppVersion .Values.buildId | quote }}The `quote` Function
`quote` wraps a value in double quotes, escaping special characters:
# Basic quoting
{{ quote .Values.config.message }}
# Input: Hello "World"
# Output: "Hello \"World\""
# CRITICAL for annotations and labels with special chars
metadata:
annotations:
description: {{ .Values.description | quote }}
# Without quote: description: My app: the best β YAML ERROR (colon)
# With quote: description: "My app: the best" β Valid YAML
labels:
version: {{ .Values.version | quote }}
# Without quote: version: 1.0 β parsed as float
# With quote: version: "1.0" β kept as stringWhen to Quote
| Scenario | Without `quote` | With `quote` | Need Quote? |
|---|---|---|---|
| Simple alphanumeric | `myapp` | `βmyappβ` | Optional |
| Contains colon | YAML error | `βvalue: hereβ` | Yes |
| Contains hash | Truncated | `βvalue # hereβ` | Yes |
| Numeric string | Parsed as number | `β1.0β` | Yes |
| Boolean-like | Parsed as bool | `βtrueβ` | Yes |
| Empty string | Missing | `""` | Yes |
# Real-world: Prometheus annotations
metadata:
annotations:
prometheus.io/scrape: {{ .Values.metrics.enabled | quote }}
prometheus.io/port: {{ .Values.metrics.port | quote }}
prometheus.io/path: {{ .Values.metrics.path | quote }}`squote` β Single Quotes
# squote uses single quotes instead of double
{{ squote .Values.password }}
# β 'mysecretpassword'
# Useful for shell commands in containers
command:
- /bin/sh
- -c
- echo {{ squote .Values.message }}The `default` Function
`default` returns a fallback value when the input is empty, nil, zero, or false:
# Basic usage
{{ default "nginx" .Values.image.repository }}
# If .Values.image.repository is set: β its value
# If .Values.image.repository is empty: β "nginx"
# Common Kubernetes patterns
image: {{ default "latest" .Values.image.tag }}
replicas: {{ default 1 .Values.replicas }}
namespace: {{ default .Release.Namespace .Values.namespace }}What Triggers `default`
| Value | Triggers default? |
|---|---|
| `""` (empty string) | β |
| `nil` / undefined | β |
| `0` (zero) | β |
| `false` | β |
| `[]` (empty list) | β |
| `{}` (empty map) | β |
| `βanythingβ` | β |
| `1` or more | β |
| `true` | β |
# Chain defaults with other functions
metadata:
labels:
app: {{ default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" | quote }}
version: {{ default .Chart.AppVersion .Values.image.tag | quote }}
# Resource limits with defaults
resources:
limits:
cpu: {{ default "500m" .Values.resources.limits.cpu | quote }}
memory: {{ default "256Mi" .Values.resources.limits.memory | quote }}
requests:
cpu: {{ default "200m" .Values.resources.requests.cpu | quote }}
memory: {{ default "128Mi" .Values.resources.requests.memory | quote }}Combining All Three
# Full deployment label block
metadata:
name: {{ printf "%s-%s" .Release.Name (default .Chart.Name .Values.nameOverride) }}
labels:
app.kubernetes.io/name: {{ default .Chart.Name .Values.nameOverride | quote }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/version: {{ default .Chart.AppVersion .Values.image.tag | quote }}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | quote }}
# ConfigMap with safe values
data:
DATABASE_URL: {{ printf "postgresql://%s:%s@%s:%d/%s"
(default "postgres" .Values.db.user)
(default "password" .Values.db.password)
(default "localhost" .Values.db.host)
(default 5432 .Values.db.port | int)
(default "mydb" .Values.db.name) | quote }}Helper Template Pattern
{{/* templates/_helpers.tpl */}}
{{/* Generate image reference */}}
{{- define "myapp.image" -}}
{{ print (default "docker.io" .Values.image.registry) "/" .Values.image.repository ":" (default .Chart.AppVersion .Values.image.tag) }}
{{- end }}
{{/* Generate fullname with defaults */}}
{{- define "myapp.fullname" -}}
{{ printf "%s-%s" .Release.Name (default .Chart.Name .Values.fullnameOverride) | trunc 63 | trimSuffix "-" }}
{{- end }}Common Issues
| Issue | Cause | Fix |
|---|---|---|
| YAML parse error on colons | Unquoted value with `:` | Pipe through `quote` |
| `1.0` becomes float | YAML type inference | Use `quote` for version strings |
| `βtrueβ` becomes boolean | YAML type inference | Use `quote` to preserve string |
| Default not triggering | Value is `0` or `false` intentionally | Use `ternary` or `if` instead |
| Spaces in print output | Using `cat` instead of `print` | Switch to `print` for no-space concat |
| Nested quotes broken | Double-escaping | Use `squote` for outer, `quote` for inner |
Best Practices
- Always `quote` annotations and labels β prevents YAML parsing surprises
- Use `default` for every optional value β makes charts self-documenting
- Prefer `printf` over `print` β format strings are more readable
- Quote numeric strings β version numbers, port strings, boolean-like values
- Chain functions with pipes β `{{ .Values.name | default βappβ | quote }}`
- Test with `helm template` β always verify output before deploying
Key Takeaways
- `print` concatenates without spaces (vs `cat` which adds spaces)
- `printf` uses Go format verbs (`%s`, `%d`) for structured string formatting
- `quote` wraps in double quotes and escapes β essential for YAML safety
- `default` provides fallback for empty/nil/zero/false values
- Combine all three for robust, self-documenting Helm templates

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
