SuperProdfor Kubenetes
Guide

Struct Tags

Using struct tags to map environment variables

master

Overview

Struct tags give you precise control over how envconfig maps environment variables to your Go struct fields. This page explains every supported tag — envconfig, default, required, ignored, and split_words — so you can customize field naming, set fallback values, enforce required variables, and skip fields you don't want processed.


Prerequisites

Before working with struct tags, make sure you have:

  • Go installed (any version that supports modules)
  • The envconfig library installed in your module (see Installation below)
  • A basic understanding of Go struct definitions and environment variables
  • Familiarity with how envconfig.Process works — if you're new to the library, review the main usage guide first

Installation
  1. Initialize a Go module if you haven't already:
go mod init your/module/name
  1. Add envconfig as a dependency:
go get github.com/kelseyhightower/envconfig
  1. Import the library in your Go file:
import "github.com/kelseyhightower/envconfig"

Configuration

The following struct tags control how envconfig resolves and processes each field.

TagValue typeDefaultEffect
envconfigstringOverrides the environment variable name envconfig looks up for this field
defaultstringSets a fallback value used when no matching environment variable is found
required"true" / "false""false"When "true", causes envconfig.Process to return an error if the variable is absent
ignored"true" / "false""false"When "true", skips the field entirely — even if a matching environment variable exists
split_words"true" / "false""false"When "true", splits a CamelCase field name into UPPER_SNAKE_CASE for automatic variable name resolution

Name resolution order

When envconfig resolves the environment variable name for a field, it follows this order:

  1. If an envconfig tag is present, use that name exactly — first checking for PREFIX_TAGNAME, then TAGNAME directly.
  2. If split_words:"true" is set, split the CamelCase field name and apply the prefix: PREFIX_UPPER_SNAKE_CASE.
  3. Otherwise, uppercase the field name and apply the prefix: PREFIX_FIELDNAME.

required vs. empty values

A required:"true" field only errors when the variable is completely absent. If the variable is present but set to an empty string, envconfig accepts it without error.


Usage

Place struct tags directly on your struct fields using backtick syntax. You can combine multiple tags on the same field.

type Specification struct {
    ManualOverride1          string `envconfig:"manual_override_1"`
    DefaultVar               string `default:"foobar"`
    RequiredVar              string `required:"true"`
    IgnoredVar               string `ignored:"true"`
    AutoSplitVar             string `split_words:"true"`
    RequiredAndAutoSplitVar  string `required:"true" split_words:"true"`
}

Call envconfig.Process with a prefix to populate your struct:

var s Specification
if err := envconfig.Process("myapp", &s); err != nil {
    log.Fatal(err)
}

Using envconfig to override the variable name

By default, envconfig constructs the variable name as PREFIX_FIELDNAME (all uppercase). Use the envconfig tag when you need a specific name — for example, to match a variable set by an external system:

type Specification struct {
    ServiceHost string `envconfig:"SERVICE_HOST"`
    Debug       bool
}
export SERVICE_HOST=127.0.0.1   # matched by tag directly
export MYAPP_DEBUG=true          # matched by default PREFIX_FIELDNAME logic

If envconfig can't find MYAPP_SERVICE_HOST, it automatically falls back to looking up SERVICE_HOST directly — so the tag value is matched as a bare name when the prefixed form is absent.

Using split_words for CamelCase fields

Without split_words:"true", a field named AutoSplitVar resolves to MYAPP_AUTOSPLITVAR. With the tag, it resolves to MYAPP_AUTO_SPLIT_VAR. If the automatic splitting doesn't produce the name you want (for example, because of numbers), use the envconfig tag for a manual override instead.

Using default as a fallback

When no environment variable is found for a field tagged with default, envconfig populates the field with the tag value. This is useful for optional configuration with sensible defaults:

DefaultVar string `default:"foobar"`

Using required to enforce presence

Mark a field required:"true" when your application cannot function without that value. envconfig.Process returns an error immediately if the variable is missing:

RequiredVar string `required:"true"`

You can combine required and split_words on the same field:

RequiredAndAutoSplitVar string `required:"true" split_words:"true"`

Using ignored to skip fields

Set ignored:"true" on fields that you manage outside of envconfig, or that exist in the struct for other purposes:

IgnoredVar string `ignored:"true"`

envconfig will not read or write this field, even if a corresponding environment variable is set.


Examples

Example 1: Manual variable name override

Use the envconfig tag to map a field to a specific environment variable name, regardless of the field name or prefix.

export MYAPP_MANUAL_OVERRIDE_1="this will be the value"
type Specification struct {
    ManualOverride1 string `envconfig:"manual_override_1"`
}

func main() {
    var s Specification
    if err := envconfig.Process("myapp", &s); err != nil {
        log.Fatal(err)
    }
    fmt.Println(s.ManualOverride1)
}

Output:

this will be the value

Without this tag, envconfig would look for MYAPP_MANUALOVERRIDE1. With split_words:"true" it would look for MYAPP_MANUAL_OVERRIDE1. The explicit envconfig tag gives you full control.


Example 2: Default values

When MYAPP_DEFAULTVAR is not set, envconfig falls back to the default tag value.

# MYAPP_DEFAULTVAR is not exported
type Specification struct {
    DefaultVar string `default:"foobar"`
}

func main() {
    var s Specification
    if err := envconfig.Process("myapp", &s); err != nil {
        log.Fatal(err)
    }
    fmt.Println(s.DefaultVar)
}

Output:

foobar

Example 3: Required variable — missing variable causes an error

# MYAPP_REQUIREDVAR is not exported
type Specification struct {
    RequiredVar string `required:"true"`
}

func main() {
    var s Specification
    if err := envconfig.Process("myapp", &s); err != nil {
        log.Fatal(err) // exits: required key MYAPP_REQUIREDVAR missing value
    }
}

Output:

required key MYAPP_REQUIREDVAR missing value

Example 4: split_words automatic CamelCase splitting

export MYAPP_AUTO_SPLIT_VAR="hello"
type Specification struct {
    AutoSplitVar string `split_words:"true"`
}

func main() {
    var s Specification
    if err := envconfig.Process("myapp", &s); err != nil {
        log.Fatal(err)
    }
    fmt.Println(s.AutoSplitVar)
}

Output:

hello

Without split_words:"true", the same struct would require the variable to be named MYAPP_AUTOSPLITVAR.


Example 5: Cross-service variable lookup with a bare envconfig tag

When envconfig can't find PREFIX_TAGVALUE, it automatically tries the tag value as a bare variable name. This is useful when consuming variables set by another service or platform.

export SERVICE_HOST=127.0.0.1
export MYAPP_DEBUG=true
type Specification struct {
    ServiceHost string `envconfig:"SERVICE_HOST"`
    Debug       bool
}

func main() {
    var s Specification
    if err := envconfig.Process("myapp", &s); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Host: %s, Debug: %v\n", s.ServiceHost, s.Debug)
}

Output:

Host: 127.0.0.1, Debug: true

Troubleshooting

Symptom: envconfig.Process returns an error: required key MYAPP_MYFIELD missing value

  • Cause: A field is tagged required:"true" and the corresponding environment variable is not set.
  • Fix: Export the variable before running your application:
    export MYAPP_MYFIELD="some-value"
    
    If the field is optional, remove the required:"true" tag or add a default tag instead.

Symptom: A field is always empty even though the environment variable is set.

  • Cause 1: The environment variable name doesn't match what envconfig expects. By default, envconfig looks for PREFIX_FIELDNAME (all uppercase). A field named myField with prefix myapp requires MYAPP_MYFIELD.
  • Fix 1: Check the exact variable name envconfig constructs. Use the envconfig tag to specify the name explicitly:
    MyField string `envconfig:"MY_FIELD"`
    
  • Cause 2: The field has ignored:"true" set.
  • Fix 2: Remove the ignored tag if you want the field to be populated.

Symptom: CamelCase field name resolves to the wrong environment variable.

  • Cause: Numbers in field names are grouped into the preceding word during split_words splitting (e.g., MyField1 becomes MYAPP_MY_FIELD1, not MYAPP_MY_FIELD_1).
  • Fix: Use the envconfig tag to set the exact variable name you need:
    MyField1 string `envconfig:"MY_FIELD_1"`
    

Symptom: A field tagged with default is not populated with the default value.

  • Cause: The environment variable exists and is set to an empty string. envconfig treats a present-but-empty variable as a valid value of "", so the default is not applied.
  • Fix: Unset the variable entirely (not just set it to empty) for the default to take effect:
    unset MYAPP_MYFIELD
    

Symptom: A field with required:"true" does not error even though the variable is empty.

  • Cause: This is expected behavior. envconfig only errors when the variable is absent. A variable that is present but empty satisfies the required constraint.
  • Fix: If you need a non-empty value, implement a custom decoder or validate the field value in your application after processing.