Skip to content

Upgrading KDBL Context Lake (K-Lake)

How to upgrade (Helm)

A production deployment is installed from the Helm chart, so an upgrade is an in-place helm upgrade to a newer chart version.

Pause indexing first (0.1.37 and later)

An upgrade that changes the database schema needs an exclusive lock on the tables it alters, and it cannot take one while crawling is in progress. On a busy deployment the upgrade then waits, and the new pods do not become ready.

Maintenance mode is one switch for this. In the console, a cluster administrator opens System health (or presses ⌘K / Ctrl+K and types health) and clicks Pause ingest for upgrade on the Maintenance mode card, then resumes it there once the upgrade is done. From the command line:

kdbl-control maintenance on --reason "upgrade to 0.1.38"
# …run the helm upgrade…
kdbl-control maintenance off

It stops crawling and the background sweeps everywhere while search, the API and MCP keep serving — it pauses writing, not reading. In-flight work finishes and releases its lease rather than being killed, so nothing is lost or re-delivered.

It waits for that in-flight work to drain, then exits non-zero and prints whatever is still running rather than letting you walk into a stalled upgrade. If it names a query whose pod has already gone — connection pooling keeps one alive past its pod — end it and re-check:

kubectl exec kdbl-postgres-0 -- psql -U kdbl -d kdbl -c \
  "SELECT pid, state, now() - query_start AS running, left(query, 80)
     FROM pg_stat_activity
    WHERE state <> 'idle' AND query_start < now() - interval '1 minute';"

kubectl exec kdbl-postgres-0 -- psql -U kdbl -d kdbl -c \
  "SELECT pg_terminate_backend(<pid>);"

Nothing is lost by ending one: sweeps restart on their next tick, and crawl work is leased, so it is re-delivered rather than dropped.

Then:

helm upgrade kdbl oci://ghcr.io/kdbl-consulting/kdbl \
  --version <NEW.X.Y.Z> \
  --namespace kdbl \
  --reset-then-reuse-values
  • --reset-then-reuse-values carries your existing tier, ingress, database, and licence settings forward — override just what's changing (e.g. --set tier=large) — while taking the new chart's own defaults for everything you never set yourself.

    Use this flag, not --reuse-values

    --reuse-values also replays the previous chart's defaults, which outrank the new chart's. On releases up to 0.1.18 those defaults included a pinned image tag per component, so an upgrade would report success, move the release to the new version, and leave every pod running the old images. Charts from 0.1.19 no longer pin tags, but --reuse-values will still carry the stale ones forward out of a release installed at 0.1.18 or earlier — so use --reset-then-reuse-values for that first upgrade, and it stays the right flag afterwards. (Needs Helm 3.14 or newer; check with helm version --short.)

    • Secrets are preserved. The master key and database passwords generated on first install are kept across upgrades, so pods never rotate them underneath a running deployment.
    • The schema migrates itself. Each service applies any schema changes at boot; there's no separate migration step to run.
    • Rolling and reversible. Pods roll one pool at a time (pod disruption budgets keep all-but-one replica serving); helm rollback kdbl returns to the previous release if needed.
    • Licence renewals don't need an upgrade — set a new blob live with kdbl-control licence apply (or POST /api/licence), or, to persist it in the release, helm upgrade … --set licence.blob='KDBLLIC1.<new>'.

Confirm the upgrade landed

Helm reports on the release, so check the pods — this is the one command that tells you what is actually running:

kubectl -n kdbl get deploy,statefulset \
  -o jsonpath='{range .items[*]}{range .spec.template.spec.containers[*]}{.image}{"\n"}{end}{end}' \
  | grep kdbl-consulting | sort -u

Every ghcr.io/kdbl-consulting/* image should carry the version you upgraded to. The console shows the same thing on the System health page, whose Components table flags a version split when one pod disagrees, and kdbl-control versions prints it from the command line.

If some pods still show the old version, re-run the upgrade with --reset-then-reuse-values (see the warning above).

Preview the chart's current options at any time with helm show values oci://ghcr.io/kdbl-consulting/kdbl --version <X.Y.Z>.

Evaluation proof-of-concept stacks upgrade differently — re-run the single-command installer with the newer version; it reuses the existing environment.

Version-specific notes

Breaking or noteworthy changes per version. Newest first — check every entry between your current version and the target.

→ v0.1.52 — richer diagnostic packs

  • Nothing to do on upgrade. No schema change: helm upgrade (or poc-up.sh --version 0.1.52) rolls the pods and nothing else. Rolling back to 0.1.51 keeps working.
  • New Helm value support.singleTenant (default false). On a deployment that serves one customer, set it to true to let a tenant administrator's diagnostic pack include each component's self-report, which it otherwise withholds. Evaluation installs set it for you. Leave it off on a deployment that hosts more than one customer; MSP mode withholds the self-reports whatever the value says. See Diagnostic packs.
  • Diagnostic packs carry more. An AI assistant (MCP) section — registered clients, their sign-in sessions and how each ended, the endpoint's refusals by reason, and findings naming the likely cause — and each component's warnings and errors from the last 24 hours, which also appear on the System health page. Neither carries tokens, secrets, document text or search queries.
  • metadata-level packs pseudonymise more. Source paths in component metrics and the deployment's public addresses in its configuration are now replaced by pseudonyms; they were previously in the clear at that level.
  • Evaluation installs gain ./scripts/poc-up.sh support, which collects the whole pack into one file. See Proof of concept.
  • Deploying without the Helm chart? Give the API container a writable /tmp (an emptyDir volume) under its read-only root filesystem, as the chart does. Without it, a data warehouse's custom CA certificate cannot be written.
  • A refused token from a revoked session is now recorded under the caller's organisation, so tenant administrators see it on the AI access activity page. It was previously recorded without an organisation.

→ v0.1.51 — the old database model routes are removed

Before you upgrade

  • Move scripts off the old model routes. The single-model routes that 0.1.50 kept for one release now answer 404, and every model operation names its model; the moves are listed under The routes that moved below. Any other /api path that does not exist now answers a JSON 404 with code not_found, where an unmatched GET used to answer 405.
  • Use the 0.1.51 kdbl-control. Add --model <name> to name a model, or leave it out and the CLI uses the connection's default model. A 0.1.50 or older CLI run without --model calls the removed routes and gets 404.
  • Roll the worker before the API, as helm upgrade does. The worker applies the schema change on start-up (schema version 20261008.6). It removes the copies of each connection's default model that 0.1.50 kept on the connection's own row (every model already lives in its own table, which is not touched), and adds the columns that record who last changed the terminology. The change takes a moment and holds a brief lock on the table of database connections. Upgrading straight from a release before 0.1.50 still works: the same step copies each connection's model across first.
  • If a schema change has deadlocked on your deployment before, scale the writers and the API to zero for the upgrade and bring the worker back alone first, then the rest.
  • Check the search path (non-standard installs only). Installs on the default search path, which is every standard install, need no action. If the database account's search path was changed, run SELECT n.nspname, count(*) FROM pg_namespace n JOIN pg_class c ON c.relnamespace = n.oid WHERE n.nspname = current_user GROUP BY 1 as the kdbl database account before upgrading. No row means nothing to do. If it returns a schema holding tables and your live data is in public, run ALTER ROLE <account> SET search_path = public (or remove the stray schema once you have confirmed it holds nothing you need). If your live data is in the other schema, contact support before upgrading.

The routes that moved

Removed Use instead
/api/warehouses/:id/model/… /api/warehouses/:id/models/:model/…
/api/warehouses/:id/schema, /query, /ask, /evals, /evals/cases /api/warehouses/:id/models/:model/schema, /query, /ask, /evals, /evals/cases
?model=published or ?model=draft on /schema and /query ?state=published or ?state=draft

:model is the model's short name. A connection's model from before 0.1.50 is default, and GET /api/warehouses/:id/models lists them. See Data warehouses.

Things to know (none needs action at upgrade time)

  • Imported models whose source names mix CamelCase and acronyms get corrected attribute names on their next sync (VaR1d99Gbp becomes var_1d_99_gbp). The model editor lists any worked question or golden case that still uses the old spelling; update those.
  • Terminology now shows who last changed your organisation's wording and when. Wording saved before the upgrade shows no date until it is next saved. See Terminology.
  • Rolling back to 0.1.50 after the upgrade keeps working.
  • No Helm values change.

→ v0.1.50 — database models, AI help and Ask, tokens by tool

Before you upgrade

  • Roll the worker before the API, as helm upgrade does. The worker applies the database schema change on start-up (schema version 20261008.4). It adds tables for database models, AI help, review comments and golden cases, and copies each connection's existing model into a model named default. The MCP audit table also becomes append-only for the application. Nothing is rewritten in place, so the change takes seconds. Nothing changes for your users or their assistants.
  • If a schema change has deadlocked on your deployment before (against running workers, extract hosts or the API's own work), scale the writers and the API to zero for the upgrade and bring the worker back alone first, then the rest. Otherwise, use maintenance mode as usual.
  • Avoid editing database models while the API servers are rolling. A model published by an old-version API server after the schema change was applied is not carried over.

Things to know (none needs action at upgrade time)

  • The old model routes still work for this release only. The per-model routes (/api/warehouses/:id/models/:model/…) replace /api/warehouses/:id/model/…, /schema, /query and /evals, which keep working and act on the default model. Move scripts and pipelines to the new routes, or add --model to kdbl-control, before the next release, which removes the old routes. See Data warehouses.
  • New chart values under warehouses.runtime: assistAllowHosts (gateway hosts AI help may call; empty allows only the provider's own API), profileBudgetMs (time budget of one suggested-values request, 120 s by default), driftCheckMinutes (how often model health is re-checked, 360 by default), auditRetentionDays and auditRedactParams (query-log retention and parameter redaction). All are optional, and the defaults match previous behaviour.
  • Personal access tokens minted from now on expire within mcp.patMaxTtlDays (365 days by default). Tokens minted before the upgrade are not affected; re-mint any that should have an end date. See Tokens.
  • Raw SQL on a database can now be switched on only by a tenant administrator. A warehouse admin sees the switch disabled, with the reason.
  • AI help and Ask are off until a tenant administrator turns them on under Settings › Search & content › AI help for database models, and need the structured_sources_assist licence feature (which needs structured_sources). Ask is the only feature that sends query results to an AI provider. See AI help and Ask.
  • SQL Server catalog keys: to see the keys behind views and row counts in the new model builder, grant the service login VIEW DEFINITION (and VIEW DATABASE STATE for row counts). Without them, the builder guesses keys from column names and says so. See Set up a warehouse.

→ v0.1.49 — group picker, access check, AI token price

  • A small schema change applies automatically on upgrade: two optional columns on the tenant for the AI token price. Nothing is backfilled and the apply takes seconds. Roll the worker before the API, as helm upgrade does. No values change.
  • Who may ask on a warehouse's Connection tab is now chosen from your directory's groups by name; saved values are unchanged and show their names. A saved group no sign-in has carried is marked not seen yet. See Data warehouses.
  • Check a user's access is a new card on the same tab for tenant administrators and warehouse admins. It reads only.
  • AI token price under Settings › AI assistants is optional; until a tenant administrator sets one, the AI tokens saved card shows tokens only. See Console.
  • White-label brands that supply a wide logo now show it at the top of the expanded sidebar. A brand without one renders as before.

→ v0.1.48 — Windows logins to SQL Server warehouses

  • Nothing to do on upgrade. No schema change, no values to change.
  • New, opt-in: Windows (Kerberos) logins for data warehouses on SQL Servers that accept only Windows logins. Use the account and password on the connection form, or a keytab the cluster administrator installs with the new warehouses.kerberos values (off by default). See Data warehouses.
  • A warehouse CA certificate must be a single certificate. A bundle of several is now refused when the warehouse is saved; before, it was accepted and every connection failed. Paste the CA that issued the server's certificate.
  • If you mount your own /etc/krb5.conf into K-Lake pods, it is still used.

→ v0.1.47 — console redesign, crawl one folder, kdoc retired

Before you upgrade

  • Schedule it outside your nightly backup window. Schema changes wait while a database backup is running. Use maintenance mode as usual.
  • Check your sign-in tokens carry iss and aud. The API now requires the issuer and audience claims on every token it accepts: console sign-in, AI-assistant (MCP) tokens, and the tokens your identity provider returns to K-Lake's own sign-in server. Until now they were checked only when present. Entra ID, Okta, Google and K-Lake's own sign-in server always include both, so most installs need do nothing. Keycloak issues access tokens with no audience unless the client has an Audience mapper; without one, sign-in is refused after the upgrade with 401 and the code auth.token_missing_audience. Add the mapper first (see Other identity providers). To check, decode a current token and confirm its aud matches the tenant's configured audience. There is no setting to accept tokens without these claims.
  • Remove any values that select kdoc. The original document engine, kdoc, is retired on CPU and GPU, and no 0.1.47 image is published. If your values still select it (extract.plugin: kdoc, an extract.additionalFleets entry with plugin: kdoc, or an image override naming a kdoc build), the upgrade stops before changing anything, with a message saying what to set instead, and the running release keeps serving. The usual replacement:

    extract:
      plugin: klex
      additionalFleets:
        - plugin: kdoc2        # scanned pages and tables; gpu: {enabled: true} for a GPU
    embed:
      enabled: true            # if kdoc was your hybrid-search embedder
    

    No format loses support: klex reads the Office, HTML and text formats (and the legacy .doc, .xls and .ppt kdoc never could), and kdoc2 reads scans and tables. Hybrid search now always uses the embedding service, so without embed.enabled=true search is keyword only. Most installs need do nothing: klex has been the default engine, and the embedding service the hybrid-search embedder, since 0.1.27.

  • Raw-manifest installs (without Helm): re-apply the tunnel manifest from the 0.1.47 release if you use remote access:

    kubectl apply -f deploy/k8s/mcp-tunnel.yaml
    

    It adds the Service the Remote access card reads, so the card shows the tunnel's real state instead of Not deployed, and moves the connector to cloudflared 2026.9.3, which carries security fixes. Nothing else changes; the tunnel token stays as it is.

  • Proof of concept: ./scripts/poc-up.sh --version 0.1.47 (see Proof of concept).

What happens during and after the upgrade

  • Sources and tenants that used kdoc move to standard extraction on the first start of 0.1.47. A source or tenant default that named kdoc is cleared (so it uses klex), and a Fallback extraction step that named kdoc now names kdoc2. Work still queued for kdoc is carried over: page re-reads go to kdoc2, everything else to the default engine. Everything kdoc extracted stays indexed and searchable.
  • Scanned pages and tables are re-read automatically, for every source. Whenever kdoc2 is running, scanned pages, pages the standard extractor read poorly, and tables it couldn't structure are re-read by kdoc2, with nothing to switch on. A source with a Fallback extraction step now hands those pages over as each file is extracted rather than in the background. To keep a source out of this, set "on_unread_tables": false on its Fallback extraction step. That turns off all of these re-reads for the source, scanned pages included; before 0.1.47 it stopped only the hand-off at extraction time. Files that fail extraction still fall back as before.
  • Re-extract PDFs once to restore attachment text. The standard extractor now keeps the text of files attached to a PDF (an e-invoice's XML, an attached document) apart from the PDF's pages, so re-reading a page for its tables or its scan no longer deletes it. PDFs indexed before 0.1.47 keep the old layout until they are re-extracted, and a PDF whose last page was already re-read has lost its attachment text. The upgrade itself re-extracts nothing. To restore the text and protect the rest, re-extract each source's PDFs once after the upgrade (the standard extractor reads a PDF in well under a second):

    kdbl-control crawl --source-id '<source-id>' --force-reextract --only-ext pdf
    

    or POST /api/sources/<id>/crawl with {"force_reextract": true, "force_reextract_extensions": ["pdf"]}. A re-extracted PDF is offered to the automatic re-read again on its own.

Changes you may notice

  • A redesigned console. A grouped sidebar with clearer page names, Settings split into sections, and a command palette (⌘K / Ctrl+K). Page addresses are unchanged. See the UI guide and Keyboard shortcuts.
  • Moved settings. MCP clients, source visibility and terminology are now under Settings › AI assistants, no longer on AI access (MCP). Old links redirect.
  • New in the console: turning a source off and on (Enabling and disabling), limiting a source to one folder (Crawling one folder), pages per second and a run average on the extraction card (Content extraction), Databases › Query audit (Data warehouses) and Failed work (UI guide).
  • Rolling back after setting a tenant's default language. Releases before 0.1.47 don't recognise a tenant's Default language (under Branding), and ignore that tenant's whole branding (logo, colours, display name, links) until it is cleared. Before rolling back, set Default language to "The same as the deployment" for every tenant that changed it. If you might roll back, don't set it yet. The deployment-wide default (branding.defaultLocale in the chart) has no such effect.

  • Azure Marketplace: the "Use GPU for enhanced extraction" option is removed. The document engine still uses a GPU node pool when you add one.

  • Earlier versions of the kdoc images stay available, so an existing installation, or a rollback to one, still pulls.

→ v0.1.46 — plain-English search, metadata fields, console HTTPS, self-service sign-in

Before you upgrade

  • Schedule it outside your nightly backup window. The upgrade applies schema changes and then builds new indexes in the background. Both wait while a database backup is running, so an upgrade that overlaps the backup finishes late. Use maintenance mode as usual.
  • Proof of concept: upgrade with the 0.1.46 kit's installer. From this release an upgrade keeps enrichment, hybrid search and plain-English reading without the flags being repeated (see Proof of concept). With an older kit, repeat every flag the evaluation was installed with.

What happens during and after the upgrade

  • Indexes build in the background. On a large estate, some new indexes take from minutes to a few hours to build after the pods are up. Search works throughout, and filters that use a new index get faster once it's there. Builds are coordinated across pods and retried by themselves, with no restart needed. kdbl-control status --include-cluster lists any index that's still building, and kdbl_deferred_indexes_incomplete counts them (see Telemetry).
  • Classification is re-derived once, in the background. The built-in scheme now rates health records, HR sickness records and documents holding passwords, API keys or private keys as restricted. It no longer rates a press release or a 10-K confidential because of an investor-relations or press email address. Existing files are re-rated from the results already stored for them, so there is no model re-run for most files. Only the few whose stored results cannot decide the new rules are classified again. Expect some levels to change. See Data classification.
  • Repeated disclaimers are learned for existing sources in the background, with no re-extraction. See Sources.

New, and off until you turn it on

  • Plain-English search reading for AI assistants: search.interpretQueries=true in the chart, or --interpret-queries on a proof of concept. See Asking in plain English.
  • The console's HTTPS certificate page (Settings › Security › HTTPS certificate). It is always on for a proof of concept. Other installs turn it on with console.tls.managed=true. After installing a certificate, register the console's https://…/authn/callback redirect URI with your sign-in provider. The MCP address doesn't change. See Console HTTPS certificate.

Changes you may notice

  • Tenant administrators of a self-managed tenant (no partner or platform operator running it) can now do every setup step from Settings without the cluster-admin token: sign-in, MCP clients and endpoint, directory secrets, and users and roles. On a single-customer deployment they can also apply the licence and change MCP Setup. A sign-in change that would lock administrators out now asks for confirmation. Over the API that is a 409 until the request repeats with acknowledge_lockout: true. See Setting up sign-in for your admins and Hosting many customers.
  • Each user's AI session lists only the tools they can use. The two warehouse tools appear only for users who can question a warehouse, and data_estate_summary appears only for tenant administrators. Copilot Studio reads the tool list once, when the agent is built, so build (or refresh) a warehouse agent with an account that has warehouse access. See Data warehouses.
  • The retrieval block of a search_content reply is smaller. It always carries sources_searched, hybrid_count and lexical_count. It lists hybrid_sources / lexical_sources only while a list holds 50 IDs or fewer. A client that read those lists should read the counts. See MCP server.

→ v0.1.45 — identifier-parts search for existing deployments

  • Schema changes apply automatically on upgrade. Nothing else is required.
  • Optional: part-of-identifier search. Keyword search can match part of an underscore-joined identifier — kozijn finds IFC_kozijn_90x114, while a passage holding the word on its own still ranks higher. New installs have it already. An existing deployment enables it once, in a quiet ingest window, with --set search.identifierPartsRebuild=true (proof of concept: ./scripts/poc-up.sh --set search.identifierPartsRebuild=true), watches kdbl_bm25_parts_partitions and kdbl_bm25_parts_ready, and can set it back to false once it is live (leaving it on is harmless). It runs online, search is unchanged until it finishes, and it stops itself if the new index grows far beyond its expected size. Plan for free disk of about 1.5× your current keyword index while it runs. Until you enable it, search behaves exactly as before. Full steps, including what to do if the logs report a wedged build, are in Production deployment.

→ v0.1.44 — per-tenant secrets, MCP hardening, data warehouses

Before you upgrade

  • Upgrade the worker before the API. Stored credentials are now sealed per tenant and bound to the row they belong to (see Security overview). Existing secrets are resealed automatically the first time the new worker starts. The chart rolls the components for you; if you roll images by hand, roll the worker first. To confirm the migration finished, or after restoring an older backup, run kdbl-control secret reseal --dry-run (and without --dry-run to rewrite anything it reports) — see secret reseal.
  • Update SIEM filters for warehouse questions. The warehouse query log's tracing target is renamed from warehouse.query to warehouse.audit. See Data warehouses — Stream to your SIEM.

MCP

  • The cluster-admin token no longer works on the MCP endpoint. It is refused with 403 (cluster_admin_refused). Connect assistants — and run kdbl-control mcp smoke — with a tenant user's sign-in or a tenant PAT.
  • Personal access tokens need a scope on MCP. A PAT with no scopes still works on the MCP endpoint for this release only; each use is logged and counted, and the KdblMcpScopeGraceInUse alert fires while any is in use. Re-mint those tokens with the mcp scope (or search / read); tokens minted from the console's MCP Tokens card already qualify. A PAT scoped only admin is refused. See Token scopes.
  • Per-user request limits apply on every deployment (10 requests a second, burst 40, by default), with failed sign-in throttling per address and per token. See Exposing MCP to the internet.

Extraction

  • The default per-file extraction ceiling is now 2 GiB (was 50 MiB), so large engineering models, drawings and media-heavy documents are extracted instead of being skipped as oversize. If your default extraction engine is kdoc rather than klex, set extractHost.maxBytes to what that engine's memory limit can handle — 50 MiB was its guard. See Sizing.
  • Re-extract to pick up this release's extraction fixes on files already indexed. A forced crawl can now be narrowed to file types:

    # PDFs: page numbers no longer shift after a blank or scanned page
    kdbl-control crawl --source-id '<source>' --force-reextract --only-ext pdf
    # CAD drawings and models: DXF, STEP and IFC are now read, and read more cleanly
    kdbl-control crawl --source-id '<source>' --force-reextract --only-ext dxf,dwg,stp,step,p21,ifc
    # WebP scans are now OCR'd
    kdbl-control crawl --source-id '<source>' --force-reextract --only-ext webp
    

Tenants

  • On a deployment hosting many customers, new tenants start with a restricted source policy: no sources that authenticate as the deployment's own cloud identity, and no NFS sources, until a cluster administrator allows them (kdbl-control tenant source-policy). Existing tenants keep working unchanged. On every deployment, a source whose endpoint is a cloud-metadata, loopback or link-local address is refused. See Hosting many customers.
  • Deleting a tenant is asynchronous: DELETE /api/tenants/:slug returns 202, and the tenant is purged in the background.

Chart

  • helm upgrade --reuse-values no longer fails when a release adds a new configuration value. It still replays the previous release's defaults, so --reset-then-reuse-values remains the recommended flag.

→ v0.1.41 — data classification and enrichment v2

  • New: data classification. An opt-in classify Smart Action per source; a tenant scheme with levels, detectors, markings and categories; rules that gate search and MCP by level; a Classification page, file badges and overrides in the console. See data classification.
  • The enrichment fleet moved to a new model generation. The enrichment image is larger and needs more memory on CPU: keep the shipped 12 Gi limit (an 8 Gi pod is killed on its first long document). On a large estate plan GPUs for it — see the sizing guide before enabling classification on hundreds of thousands of documents.
  • Schema upgrade is applied automatically by the first worker to start, as usual. On a busy estate the apply may wait for locks behind running crawls; from this version the upgrading pods stay healthy while they wait instead of being restarted.
  • Existing knowledge graphs are tidied. Generic words recorded as entities by earlier versions ("Company", "customers", "world") are removed by the maintenance sweep, with their mentions and relations. Nothing needs re-enriching.
  • Built-in scheme changes re-classify. A tenant that has never saved a classification scheme runs on the built-in one; a release that changes it re-classifies that tenant's files in the background. Tenants with a saved scheme are unaffected.
  • Console: the dashboard's Failed count now shows your own tenant's abandoned pipeline steps, listed with the reason each gave up; each can be retried or discarded.

→ v0.1.2 — Licensing is now enforced (breaking)

K-Lake is now fail-closed: every K-Lake service container refuses to start without a valid licence. An existing v0.1.1 deployment that rolls the v0.1.2 images without a licence provisioned will fail to start (CrashLoop) with:

Error: no licence applied: set the kdbl-licence Secret (KDBL_LICENCE or
KDBL_LICENCE_FILE) — refusing to start

Before you upgrade

  1. Obtain a licence. If you don't already have one, ask KDBL for a licence (evaluations get a 30-day one). It's a KDBLLIC1.… blob.

  2. Provide the licence. On a Helm deployment, pass it as a chart value — the chart creates and wires the Secret for you:

helm upgrade kdbl oci://ghcr.io/kdbl-consulting/kdbl --reset-then-reuse-values \
  --set licence.blob='KDBLLIC1.<...the blob...>'

On a manifest/POC deployment, create the kdbl-licence Secret directly:

kubectl -n kdbl create secret generic kdbl-licence \
  --from-literal=licence='KDBLLIC1.<...the blob...>'

Verify it first if you like — kdbl-control licence inspect <file> prints the terms and confirms ✓ signature valid.

  1. Then roll the images. Each pod reads KDBL_LICENCE from that Secret at boot; the chart (or the standard deployment manifests) already wires it. Confirm each container logs that the licence was accepted at boot and stays Running.

The standard install scripts now require $KDBL_LICENCE and refuse to run without it, so fresh installs can't accidentally come up unlicensed.

What enforcement does (once running)

A running deployment is not killed when a licence lapses — it degrades gracefully per the licence's grace/lockdown windows: full use → (expired) grace → new-ingestion blocked (reads still work) → fully blocked. The API always stays up to serve /licence so you can apply a renewal live (kdbl-control licence apply) without a restart. See Licensing.

Notes

  • The old KDBL_LICENCE_REQUIRED env flag is removed — enforcement is unconditional. Drop it from any manifests/overlays.
  • Renewals: update the kdbl-licence Secret (newest licence wins) + restart, or apply live via POST /api/licence.