nicolargo/glances · warning · ValueError

Invalid CQL identifier for '{name}': {value!r}. Only letters

Error message

Invalid CQL identifier for '{name}': {value!r}. Only letters, digits, and underscores are allowed, and it must start with a letter.

What it means

The Cassandra export validates keyspace and table names against ^[a-zA-Z][a-zA-Z0-9_]*$ to prevent CQL injection through configuration values. Any keyspace/table containing hyphens, dots, spaces, quotes, or starting with a digit/underscore raises this ValueError from __init__. The outer __init__ catches it, logs 'Cassandra configuration error', and disables the export (export_enable = False), so Glances keeps running without Cassandra export.

Source

Thrown at glances/exports/glances_cassandra/__init__.py:30

import sys
from datetime import datetime
from numbers import Number

from cassandra import InvalidRequest
from cassandra.auth import PlainTextAuthProvider
from cassandra.cluster import Cluster
from cassandra.util import uuid_from_time

from glances.exports.export import GlancesExport
from glances.logger import logger

_CQL_IDENTIFIER_RE = re.compile(r'^[a-zA-Z][a-zA-Z0-9_]*$')


def _validate_cql_identifier(value, name):
    """Raise ValueError if value is not a safe CQL identifier."""
    if not _CQL_IDENTIFIER_RE.match(str(value)):
        raise ValueError(
            f"Invalid CQL identifier for '{name}': {value!r}. "
            "Only letters, digits, and underscores are allowed, and it must start with a letter."
        )
    return str(value)


class Export(GlancesExport):
    """This class manages the Cassandra/Scylla export module."""

    def __init__(self, config=None, args=None):
        """Init the Cassandra export IF."""
        super().__init__(config=config, args=args)

        # Mandatory configuration keys (additional to host and port)
        self.keyspace = None

        # Optional configuration keys
        self.protocol_version = 3

View on GitHub (pinned to a240d8dfb3)

Solutions

  1. Rename the keyspace/table to match [a-zA-Z][a-zA-Z0-9_]* (e.g. my_keyspace instead of my-keyspace).
  2. If you must keep a non-conforming name, create a compatible view/table alias in Cassandra or patch _validate_cql_identifier locally — upstream intentionally rejects it for injection safety.
  3. Check glances.log for 'Cassandra configuration error' to confirm this validation is what disabled the export.

Example fix

# before
[export_cassandra]
keyspace=glances-data

# after
[export_cassandra]
keyspace=glances_data
Defensive patterns

Strategy: validation

Validate before calling

import re
_CQL = re.compile(r'^[a-zA-Z][a-zA-Z0-9_]*$')
assert _CQL.match(keyspace) and _CQL.match(table), 'use plain CQL identifiers'

Type guard

def is_valid_cql_identifier(v: str) -> bool:
    return bool(re.match(r'^[a-zA-Z][a-zA-Z0-9_]*$', v))

Prevention

When it happens

Trigger: Setting export_cassandra_keyspace or export_cassandra_table in glances.conf to values like 'my-keyspace', 'glances.table', '1space', or '_t'. Only plain identifiers are accepted — no quoting, no dotted keyspaces.

Common situations: Pointing Glances at an existing keyspace whose real name contains a hyphen (common in Cassandra naming), or copy-pasting a table name with quotes/spaces from CQLSH.

Related errors


AI-assisted analysis of nicolargo/glances@a240d8dfb3 (2026-08-27). Data as JSON: /api/errors/208e8e6b2f4224be. Report an issue: GitHub.