SigNoz/signoz · error · errors.Error
CodeLicenseUnavailable
CodeLicenseUnavailable
Error message
a valid license is not available
What it means
parseMetricsDuration accepts either a float interpreted as seconds or a Prometheus-style duration string (prommodel.ParseDuration: '5m', '1h30m', '1d'); if both fail it returns 'cannot parse %q to a valid duration'. Used for step and similar parameters of the metrics query APIs.
Source
Thrown at ee/authz/openfgaauthz/provider.go:181
return provider.pkgAuthzService.CreateManagedRoles(ctx, orgID, managedRoles)
}
func (provider *provider) CreateManagedUserRoleTransactions(ctx context.Context, orgID valuer.UUID, userID valuer.UUID) error {
tuples := make([]*openfgav1.TupleKey, 0)
grantTuples := provider.getManagedRoleGrantTuples(orgID, userID)
tuples = append(tuples, grantTuples...)
managedRoleTuples := provider.getManagedRoleTransactionTuples(orgID)
tuples = append(tuples, managedRoleTuples...)
return provider.Write(ctx, tuples, nil)
}
func (provider *provider) Create(ctx context.Context, orgID valuer.UUID, role *authtypes.Role) error {
_, err := provider.licensing.GetActive(ctx, orgID)
if err != nil {
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
existingRole, err := provider.GetByOrgIDAndName(ctx, orgID, role.Name)
if err != nil && !errors.Asc(err, authtypes.ErrCodeRoleNotFound) {
return err
}
if existingRole != nil {
return errors.Newf(errors.TypeAlreadyExists, authtypes.ErrCodeRoleAlreadyExists, "role with name: %s already exists", existingRole.Name)
}
tuples, err := authtypes.NewTuplesFromTransactionGroups(role.Name, orgID, role.TransactionGroups)
if err != nil {
return err
}
err = provider.Write(ctx, tuples, nil)
if err != nil {View on GitHub (pinned to 5069bf80b0)
Solutions
- Use Prometheus duration syntax: '10s', '5m', '1h', '1d' or combinations like '1h30m'
- Or send a plain number meaning seconds ('60')
- Sanitize whitespace and validate with a regex like ^[0-9]+(ms|s|m|h|d)$ or ^[0-9.]+$ client-side
Example fix
# before curl '.../api/v1/query_range?step=PT5M' # after curl '.../api/v1/query_range?step=5m'
Defensive patterns
Strategy: validation
Validate before calling
var stepRe = regexp.MustCompile(`^([0-9]+(\.[0-9]+)?|([0-9]+(ms|s|m|h|d))+)$`)
if !stepRe.MatchString(stepParam) { /* reject before request */ } Type guard
null
Try / catch
null
Prevention
- Use Prometheus duration syntax, not ISO-8601 or Go duration
- Trim whitespace client-side
- Send plain seconds for fixed steps
When it happens
Trigger: Calling queryRangeMetrics/queryMetrics with a step value like '60s ' (trailing space), '1 hr' (space inside), ISO durations ('PT1H'), or a non-numeric string such as 'hour' — none parse as float or Prometheus duration.
Common situations: Copy-pasting ISO-8601 durations from other systems; frontend formatting bugs inserting spaces or unicode; assuming Go's time.ParseDuration syntax ('1h30m') where only Prometheus units (no 'us', different day handling) are supported.
Related errors
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/3b69bb5ed949a9fb.
Report an issue: GitHub.