GoogleContainerTools/skaffold · error

sync rule pattern '%s' does not have prefix '%s'

Error message

sync rule pattern '%s' does not have prefix '%s'

What it means

validateSyncRules checks manual sync rules: each rule's Src file pattern must start with its Strip prefix, since Strip removes that prefix from the source path before mapping to the container. If Src doesn't begin with Strip, the mapping is nonsensical and validation fails.

Source

Thrown at pkg/skaffold/schema/validation/validation.go:559

		if v.IsNil() {
			return nil
		}
		return visitStructs(cfg, v.Elem(), visitor)

	default:
		// other values are fine
		return nil
	}
}

// validateSyncRules checks that all manual sync rules have a valid strip prefix
func validateSyncRules(cfg *parser.SkaffoldConfigEntry, artifacts []*latest.Artifact) []ErrorWithLocation {
	var cfgErrs []ErrorWithLocation
	for i, a := range artifacts {
		if a.Sync != nil {
			for _, r := range a.Sync.Manual {
				if !strings.HasPrefix(r.Src, r.Strip) {
					err := fmt.Errorf("sync rule pattern '%s' does not have prefix '%s'", r.Src, r.Strip)
					cfgErrs = append(cfgErrs, ErrorWithLocation{
						Error:    err,
						Location: cfg.YAMLInfos.LocateField(cfg.Build.Artifacts[i], "Sync"),
					})
				}
			}
		}
	}
	return cfgErrs
}

// validatePortForwardResources checks that all user defined port forward resources
// have a valid resourceType
func validatePortForwardResources(cfg *parser.SkaffoldConfigEntry, pfrs []*latest.PortForwardResource) []ErrorWithLocation {
	var errs []ErrorWithLocation
	validResourceTypes := map[string]struct{}{
		"container":             {},
		"pod":                   {},

View on GitHub (pinned to a1189de023)

Solutions

  1. Make strip a genuine prefix of src, e.g. src: 'src/app/**' with strip: 'src/'
  2. Set strip to '' if you don't need prefix stripping
  3. Verify each manual rule maps host paths under Src to the container path after removing Strip

Example fix

// before
sync:
  manual:
    - src: 'src/**/*.js'
      strip: 'dist/'
// after
sync:
  manual:
    - src: 'src/**/*.js'
      strip: 'src/'
Defensive patterns

Strategy: validation

Validate before calling

// Go: each sync rule's strip must be a prefix of src
func validSyncRule(src, strip string) bool { return strings.HasPrefix(src, strip) }

Try / catch

if !validSyncRule(rule.Src, rule.Strip) {
	return fmt.Errorf("sync rule src %q must start with strip %q", rule.Src, rule.Strip)
}

Prevention

When it happens

Trigger: An artifact's sync.manual rule has a strip value that is not a prefix of src, e.g. src: 'src/**/*.js' with strip: 'dist/', detected via strings.HasPrefix(r.Src, r.Strip).

Common situations: Copy-pasting sync rules from another project and editing src but not strip, or setting strip to the container-side path instead of the host-side prefix.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/b6701ea0b0c69a99. Report an issue: GitHub.