vitessio/vitess · error
not allowed: read-only security-policy enforced
Error message
not allowed: read-only security-policy enforced
What it means
When fetching table sizes per shard, vtadmin selects one random serving tablet from each shard to query. If a shard has no tablets in the SERVING state, the query cannot proceed and this wrapped ErrNoServingTablet error is returned for that shard.
Source
Thrown at go/acl/read_only_policy.go:24
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package acl
import (
"errors"
"net/http"
)
var errReadOnly = errors.New("not allowed: read-only security-policy enforced")
// readOnlyPolicy allows DEBUGGING and MONITORING roles for everyone,
// while denying any other roles (e.g. ADMIN) for everyone.
type readOnlyPolicy struct{}
// CheckAccessHTTP disallows all HTTP access.
func (readOnlyPolicy) CheckAccessHTTP(req *http.Request, role string) error {
switch role {
case DEBUGGING, MONITORING:
return nil
default:
return errReadOnly
}
}
func init() {
RegisterPolicy("read-only", readOnlyPolicy{})
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Start or restore at least one serving tablet for the affected shard (vtctldclient StartTablet / restart vttablet)
- Check tablet states with vtctldclient GetTablets and fix any tablets stuck non-serving
- Prune truly dead shards/tablets from the topology if the shard is intentionally retired
Defensive patterns
Strategy: validation
Validate before calling
serving := 0
for _, t := range tablets {
if t.Tablet.Keyspace == ks && t.Tablet.Shard == shard && t.State == vtadminpb.Tablet_SERVING {
serving++
}
}
if serving == 0 { return errors.New("shard has no serving tablets; skip or fix before calling") } Type guard
func hasServingTablet(tablets []*vtadminpb.Tablet, ks, shard string) bool {
for _, t := range tablets {
if t.Tablet.Keyspace == ks && t.Tablet.Shard == shard && t.State == vtadminpb.Tablet_SERVING {
return true
}
}
return false
} Prevention
- Check tablet serving states before issuing schema/size queries per shard
- Keep at least one serving tablet per shard during maintenance windows
- Alert on shards with zero SERVING tablets
When it happens
Trigger: Calling a table-size / schema RPC that iterates shards when a shard in the keyspace has zero tablets with State == Tablet_SERVING (all replicas drained, only non-serving tablets present).
Common situations: A shard whose tablets are all down for maintenance; a newly created shard before tablets are started; tablets stuck in a non-serving state after a failed restart; wrong cluster selected in vtadmin config.
Related errors
- invalid joined path
- ErrNoTablet
- not allowed: deny-all security-policy enforced
- invalid choice for enum
- value must be either a float64 (interpreted as seconds) or a
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/460a9cba11304d72.
Report an issue: GitHub.