caddyserver/caddy · error

invalid action type

Error message

invalid action type

What it means

filterAction.IsValid() in the logging module rejects any query-filter action type that is not one of the three literals 'replace', 'hash', or 'delete'. It is returned by QueryFilter.Validate() during config provisioning, so it fails at load time, never at request time. The value comes straight from the 'type' field of an action object in the query filter config.

Source

Thrown at modules/logging/filters.go:306

const (
	// Replace value(s).
	replaceAction filterAction = "replace"

	// Hash value(s).
	hashAction filterAction = "hash"

	// Delete.
	deleteAction filterAction = "delete"
)

func (a filterAction) IsValid() error {
	switch a {
	case replaceAction, deleteAction, hashAction:
		return nil
	}

	return errors.New("invalid action type")
}

type queryFilterAction struct {
	// `replace` to replace the value(s) associated with the parameter(s), `hash` to replace them with the 4 initial bytes of the SHA-256 of their content or `delete` to remove them entirely.
	Type filterAction `json:"type"`

	// The name of the query parameter.
	Parameter string `json:"parameter"`

	// The value to use as replacement if the action is `replace`.
	Value string `json:"value,omitempty"`
}

// QueryFilter is a Caddy log field filter that filters
// query parameters from a URL.
//
// This filter updates the logged URL string to remove, replace or hash
// query parameters containing sensitive data. For instance, it can be

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Change the action type to exactly one of: replace, hash, or delete (lowercase)
  2. If using the Caddyfile, use the documented forms: replace <param> <value>, hash <param>, delete <param>
  3. Validate the logging config with caddy validate --config <file> --adapter <adapter> before deploying
  4. If 'replace' is chosen, also include the required 'value' field

Example fix

// before
{
  "logs": {
    "log0": {
      "encoder": {
        "format": "filter",
        "wrap": {"format": "json"},
        "fields": {
          "uri": {
            "filter": "query",
            "actions": [{"type": "redact", "parameter": "token"}]
          }
        }
      }
    }
  }
}

// after
"actions": [{"type": "delete", "parameter": "token"}]
Defensive patterns

Strategy: validation

Validate before calling

var validActions = map[string]bool{"replace": true, "hash": true, "delete": true}

func validateQueryFilter(cfg map[string]any) error {
	for _, f := range cfg["actions"].([]any) {
		a := f.(map[string]any)
		if !validActions[a["type"].(string)] {
			return fmt.Errorf("invalid action type %q: use replace, hash, or delete", a["type"])
		}
	}
	return nil
}

Type guard

type FilterAction string

func (a FilterAction) Valid() bool {
	switch a {
	case "replace", "hash", "delete":
		return true
	}
	return false
}

Prevention

When it happens

Trigger: JSON config with log encoder filter {"filter": "query", "actions": [{"type": "redact", "parameter": "token"}]}; typo like "delelte" or "Hash" (case-sensitive); passing an action object without a recognized type value.

Common situations: Hand-writing the logs JSON config instead of using the Caddyfile syntax; porting a redaction config from another tool whose action names differ (e.g. 'remove', 'mask'); uppercase or localized variants of the action names.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/de0fe81d4aeca67a. Report an issue: GitHub.