{"record":{"id":"715931a14791dea6","repo":"docker/cli","slug":"s-flag-requires-the-rotate-flag-to-update","errorCode":null,"errorMessage":"`--%s` flag requires the `--rotate` flag to update the CA","messagePattern":"`--(.+?)` flag requires the `--rotate` flag to update the CA","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/swarm/ca.go","lineNumber":69,"sourceCode":"\tflags.Var(&opts.rootCAKey, flagCAKey, \"Path to the PEM-formatted root CA key to use for the new cluster\")\n\n\tflags.BoolVarP(&opts.detach, \"detach\", \"d\", false, \"Exit immediately instead of waiting for the root rotation to converge\")\n\tflags.BoolVarP(&opts.quiet, \"quiet\", \"q\", false, \"Suppress progress output\")\n\treturn cmd\n}\n\nfunc runCA(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet, opts caOptions) error {\n\tapiClient := dockerCLI.Client()\n\n\tres, err := apiClient.SwarmInspect(ctx, client.SwarmInspectOptions{})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !opts.rotate {\n\t\tfor _, f := range []string{flagCACert, flagCAKey, flagCertExpiry, flagExternalCA} {\n\t\t\tif flags.Changed(f) {\n\t\t\t\treturn fmt.Errorf(\"`--%s` flag requires the `--rotate` flag to update the CA\", f)\n\t\t\t}\n\t\t}\n\t\treturn displayTrustRoot(dockerCLI.Out(), res)\n\t}\n\n\tif flags.Changed(flagExternalCA) && len(opts.externalCA.Value()) > 0 && !flags.Changed(flagCACert) {\n\t\treturn fmt.Errorf(\n\t\t\t\"rotating to an external CA requires the `--%s` flag to specify the external CA's cert - \"+\n\t\t\t\t\"to add an external CA with the current root CA certificate, use the `update` command instead\", flagCACert)\n\t}\n\n\tif flags.Changed(flagCACert) && len(opts.externalCA.Value()) == 0 && !flags.Changed(flagCAKey) {\n\t\treturn fmt.Errorf(\"the --%s flag requires that a --%s flag and/or --%s flag be provided as well\",\n\t\t\tflagCACert, flagCAKey, flagExternalCA)\n\t}\n\n\tupdateSwarmSpec(&res.Swarm.Spec, flags, opts)\n\tif _, err := apiClient.SwarmUpdate(ctx, client.SwarmUpdateOptions{","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/swarm/ca.go#L51-L87","documentation":"Emitted by 'docker swarm ca' when a CA-modifying flag (--ca-cert, --ca-key, --cert-expiry, --external-ca) is supplied without --rotate. The command treats these flags as side effects of a rotation; without --rotate it only displays the current trust root.","triggerScenarios":"Invoking 'docker swarm ca --ca-cert ./new.pem' (or --ca-key / --cert-expiry / --external-ca) with no --rotate flag. The loop at ca.go:67-70 detects any of those flags as Changed and returns this error.","commonSituations":"Operator forgets that updating the CA is destructive and must be explicitly requested; scripting that reuses an init-style flag set for ca; typo'd --rotate (e.g. --rotat).","solutions":["Add --rotate: 'docker swarm ca --rotate --ca-cert ./new.pem'.","If you only meant to view the CA, drop the offending CA-modifying flags entirely.","Verify the exact flag name with 'docker swarm ca --help'."],"exampleFix":"# before\ndocker swarm ca --ca-cert ./new.pem\n\n# after\ndocker swarm ca --rotate --ca-cert ./new.pem","handlingStrategy":"validation","validationCode":"// Validate CA flag set before invoking\nneedsRotate := anyChanged(flags, flagCACert, flagCAKey, flagCertExpiry, flagExternalCA)\nif needsRotate && !flags.Changed(flagRotate) {\n    return errors.New(\"--rotate is required when changing CA cert/key/expiry/external-ca\")\n}","typeGuard":"func requiresRotate(flags *pflag.FlagSet) bool {\n\tfor _, f := range []string{flagCACert, flagCAKey, flagCertExpiry, flagExternalCA} {\n\t\tif flags.Changed(f) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","tryCatchPattern":null,"preventionTips":["Always pair CA-modifying flags with --rotate.","Use 'docker swarm ca --help' to confirm flag semantics.","For viewing only, pass no CA-modifying flags."],"tags":["swarm","ca","flags","validation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}