docker/compose · error

environment variable %q required by %s %q is not set

Error message

environment variable %q required by %s %q is not set

What it means

resolveFileContent reads a secret/config whose value comes from a project environment variable (secrets.<name>.environment). If that variable is absent from project.Environment at container start, compose cannot materialize the value and fails with this error naming the variable, mount type, and resource.

Source

Thrown at pkg/compose/secrets.go:114

			files[i] = types.FileReferenceConfig(config)
		}
		fileMap = make(map[string]types.FileObjectConfig)
		for k, v := range project.Configs {
			fileMap[k] = types.FileObjectConfig(v)
		}
	}
	return files, fileMap
}

func (s *composeService) resolveFileContent(project *types.Project, source types.FileObjectConfig, mountType mountType) (string, error) {
	if source.Content != "" {
		// inlined, or already resolved by include
		return source.Content, nil
	}
	if source.Environment != "" {
		env, ok := project.Environment[source.Environment]
		if !ok {
			return "", fmt.Errorf("environment variable %q required by %s %q is not set", source.Environment, mountType, source.Name)
		}
		return env, nil
	}
	return "", nil
}

func (s *composeService) copyFileToContainer(ctx context.Context, id, content string, file types.FileReferenceConfig) error {
	b, err := createTar(content, file)
	if err != nil {
		return err
	}

	_, err = s.apiClient().CopyToContainer(ctx, id, client.CopyToContainerOptions{
		DestinationPath: "/",
		Content:         &b,
		CopyUIDGID:      file.UID != "" || file.GID != "",
	})
	return err

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Set the variable before running compose: export VAR_NAME=... or add it to the project .env file.
  2. Check for typos between the environment: key in compose and the actual variable name.
  3. In automation, inject the variable through the API's project environment rather than relying on the shell.
  4. If the value should come from a file instead, switch the definition to file:.

Example fix

# before
secrets:
  api_token:
    environment: API_TOKEN   # unset
# $ docker compose up → error

# after
# .env
API_TOKEN=supersecret
# $ docker compose up
Defensive patterns

Strategy: validation

Validate before calling

func envBackedSecretsSet(project *types.Project) error {
	check := func(m map[string]types.FileObjectConfig, kind string) error {
		for name, obj := range m {
			if obj.Environment != "" {
				if _, ok := project.Environment[obj.Environment]; !ok {
					return fmt.Errorf("%s %q needs env %s which is unset", kind, name, obj.Environment)
				}
			}
		}
		return nil
	}
	if err := check(project.Secrets, "secret"); err != nil { return err }
	return check(project.Configs, "config")
}

Try / catch

if err := compose.Up(ctx, project, opts); err != nil {
    if strings.Contains(err.Error(), "required by") && strings.Contains(err.Error(), "is not set") {
        // extract var name from message, export it or add to .env, retry
    }
    return err
}

Prevention

When it happens

Trigger: Starting (up/run) a project that declares a secret or config with environment: VAR_NAME where VAR_NAME is unset in the shell, .env file, or environment passed to the compose API.

Common situations: Forgetting to export the variable or omitting it from .env; variable names differing between environments (dev vs CI); running compose from a cron/systemd context without the interactive shell's environment.

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/99c4ca7707de571b. Report an issue: GitHub.