{"record":{"id":"d68a3d4d9508bea3","repo":"mattermost-community/focalboard","slug":"appropriate-license-required","errorCode":null,"errorMessage":"appropriate license required","messagePattern":"appropriate license required","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/model/error.go","lineNumber":19,"sourceCode":"package model\n\nimport (\n\t\"database/sql\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\n\tmmModel \"github.com/mattermost/mattermost/server/public/model\"\n\n\tpluginapi \"github.com/mattermost/mattermost/server/public/pluginapi\"\n)\n\nvar (\n\tErrViewsLimitReached        = errors.New(\"views limit reached for board\")\n\tErrPatchUpdatesLimitedCards = errors.New(\"patch updates cards that are limited\")\n\n\tErrInsufficientLicense = errors.New(\"appropriate license required\")\n\n\tErrCategoryPermissionDenied = errors.New(\"category doesn't belong to user\")\n\tErrCategoryDeleted          = errors.New(\"category is deleted\")\n\n\tErrBoardMemberIsLastAdmin = errors.New(\"cannot leave a board with no admins\")\n\n\tErrRequestEntityTooLarge = errors.New(\"request entity too large\")\n\n\tErrInvalidBoardSearchField = errors.New(\"invalid board search field\")\n)\n\n// ErrNotFound is an error type that can be returned by store APIs\n// when a query unexpectedly fetches no records.\ntype ErrNotFound struct {\n\tentity string\n}\n\n// NewErrNotFound creates a new ErrNotFound instance.","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/model/error.go#L1-L37","documentation":"ErrInsufficientLicense is a sentinel error meaning the operation requires a license that is not present or does not cover the feature. Board metadata and other licensed features call the plugin API's license checks and return this error when the check fails. It indicates an entitlement problem, not a bug in the request.","triggerScenarios":"Calling GetBoardMetadata (or any licensed API) on an unlicensed/free Mattermost install, or with a license that expired or lacks the Boards entitlement; IsErrNotImplemented maps it to HTTP 501.","commonSituations":"License expired after renewal lapse; license file not uploaded after upgrade; on-prem install without the required Enterprise license; local dev environments without a trial license.","solutions":["Upload/renew a valid Mattermost Enterprise license in System Console > Edition and License","Verify the license includes the Boards/Plugins entitlement needed","If the feature is not needed, avoid calling the licensed endpoint or degrade gracefully"],"exampleFix":"// before\nmeta, err := app.GetBoardMetadata(boardID)\n// after\nmeta, err := app.GetBoardMetadata(boardID)\nif errors.Is(err, model.ErrInsufficientLicense) {\n    // fall back to unlicensed behavior or prompt admin to license\n}","handlingStrategy":"type-guard","validationCode":"license := pluginAPI.License.Get()\nif license == nil || !license.Features.Boards {\n    // avoid calling licensed endpoints; degrade gracefully\n}","typeGuard":"func isLicenseErr(err error) bool {\n    return errors.Is(err, model.ErrInsufficientLicense)\n}","tryCatchPattern":"meta, err := app.GetBoardMetadata(boardID)\nif errors.Is(err, model.ErrInsufficientLicense) {\n    return nil // render unlicensed UI instead of failing\n}","preventionTips":["Check license presence at startup and surface it to admins","Set alerts before license expiry","Gate licensed features behind capability checks"],"tags":["go","licensing","enterprise"],"backgroundTag":"license-limit-reached","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}