hashicorp/nomad · error

Reading secret file prohibited: %s

Error message

Reading secret file prohibited: %s

What it means

sanitizePath() additionally blocks access to any task's SecretsDir. If the requested path resolves inside a SecretsDir, this error is returned (checked case-insensitively by replacing /Secrets with /secrets). This protects Task Role Credentials/vault secrets from the file API.

Source

Thrown at client/allocdir/alloc_dir.go:437

	}

	requestedPath, err := filepath.Abs(filepath.Join(resolvedAllocDir, path))
	if err != nil {
		return "", fmt.Errorf("failed to resolve requested path: %w", err)
	}

	if err := escapingfs.ChildEscapesParentDir(resolvedAllocDir, requestedPath); err != nil {
		return "", fmt.Errorf("path escapes the alloc directory")
	}

	a.mu.RLock()
	defer a.mu.RUnlock()

	// Check it does not access the secrets or private directories
	for _, taskDir := range a.TaskDirs {
		rps := strings.ReplaceAll(requestedPath, "/Secrets", "/secrets")
		if err := escapingfs.ChildEscapesParentDir(taskDir.SecretsDir, rps); err == nil {
			return "", fmt.Errorf("Reading secret file prohibited: %s", path)
		}

		rpp := strings.ReplaceAll(requestedPath, "/Private", "/private")
		if err := escapingfs.ChildEscapesParentDir(taskDir.PrivateDir, rpp); err == nil {
			return "", fmt.Errorf("Reading secret file prohibited: %s", path)
		}
	}

	return requestedPath, nil
}

// Stat returns information about the file at a path relative to the alloc dir
func (a *AllocDir) Stat(path string) (*cstructs.AllocFileInfo, error) {

	sanitizedPath, err := a.sanitizePath(path)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Do not access the secrets dir via the alloc filesystem API; use the secret's intended delivery mechanism (template, env, vault integration)
  2. Move application config that must be readable out of the secrets dir into a normal task dir path
  3. If legitimate access is needed, read the file inside the task process itself rather than via AllocDir APIs

Example fix

// before
allocDir.ReadAt("task/web/secrets/token", 0)
// after
// read inside the task, e.g. via exec or template delivery, not the file API
Defensive patterns

Strategy: validation

Validate before calling

if strings.Contains(strings.ToLower(relPath), "secrets") {
    return fmt.Errorf("refusing to access secrets dir")
}

Try / catch

data, err := allocDir.ReadAt(relPath, 0)
if err != nil && strings.Contains(err.Error(), "Reading secret file prohibited") {
    return ErrSecretsAccessDenied // request is not permitted by design
}

Prevention

When it happens

Trigger: Calling List/Stat/ReadAt/BlockUntilExists/ChangeEvents with a path resolving inside a task's secrets directory (e.g. secrets/token or .../Secrets/...).

Common situations: Templates or tooling trying to read the vault-derived secret token file; filesystem snapshot/debug tooling enumerating all task files including secrets; user asking the API for secrets dir contents.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/6d46d0a345661995. Report an issue: GitHub.