Enforcing Consistent Channel Names in Mattermost with a Custom Plugin
Discover how to write a Mattermost plugin that validates channel names on creation, keeps your workspace tidy, and gives instant feedback to users.
13 Jul 2026, 06:52 UTC

1. The Problem
In a growing team, channel names can quickly become a source of confusion. Some members create channels with spaces, mixed case, or special characters, while others use abbreviations. The result is a cluttered sidebar, hard‑to‑search channels, and a higher cognitive load for new members.
Enforcing a naming convention—such as all‑lowercase, hyphen‑separated names—removes this friction. The question is how to apply the rule automatically without relying on manual moderation.
2. Why a Plugin is the Right Tool
Mattermost’s plugin framework lets you hook into server events and run Go code in the same process as the Mattermost server. For a naming policy, the ChannelCreated hook is perfect: it fires just before a channel is persisted, giving you a chance to reject the creation with a custom error message.
Alternative approaches (e.g., using the UI or a bot) would still require manual oversight or could introduce latency. A plugin provides immediate, server‑side validation and centralizes the rule in code.
3. Building the Naming‑Policy Plugin
Below is a minimal, self‑contained example that rejects any channel name that contains uppercase letters, spaces, or non‑alphanumeric characters other than hyphens.
package main
import (
"errors"
"regexp"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/plugin"
)
// ChannelPolicyPlugin implements the Mattermost plugin interface.
type ChannelPolicyPlugin struct{ plugin.MattermostPlugin }
// namePattern defines the allowed channel name format.
var namePattern = regexp.MustCompile(`^[a-z0-9-]+$`)
// ChannelCreated is called right before a channel is created.
func (p *ChannelPolicyPlugin) ChannelCreated(c *model.Channel) (*model.Channel, error) {
if !namePattern.MatchString(c.Name) {
return nil, errors.New("channel names must be lowercase, hyphen‑only, and contain no spaces or special characters")
}
return c, nil
}
// Plugin is the entry point for Mattermost.
var Plugin = &ChannelPolicyPlugin{}
Save this as main.go in a new directory. Next, add a manifest.yaml so Mattermost knows how to load the plugin:
id: channel-name-policy
name: Channel Naming Policy
description: Rejects channel names that do not match a regex.
version: 1.0.0
min_server_version: 6.0
server: plugin.go
Build the plugin:
go build -buildmode=plugin -o channel-policy.so main.go
Place channel-policy.so in the server’s plugins directory (e.g., /opt/mattermost/plugins). Then enable the plugin in mattermost.ini:
[PluginSettings]
EnableUploads=true
EnableServerPlugins=true
Finally, restart the Mattermost server to load the new plugin. After the restart, attempts to create a channel named #Project X will fail with the custom error message defined in the plugin.
4. Deploying and Testing
- Local Development
Runmmctl server startwith the plugin directory mounted. Create a channel via the UI ormmctl channel createand verify the error. - Production Deployment
Copy the compiled.soto the productionpluginsfolder, updatemattermost.iniif necessary, and restart the server. - Verify Hook Invocation
Checkmattermost.logfor entries like[plugin] ChannelCreated calledwhen a channel creation is attempted. - Test Edge Cases
Try names such as#bug-123,#Feature-Update, and# spacesto confirm the regex behaves as expected.
5. Trade‑offs and Limitations
- Server Restart Required
Any change to the plugin code requires a restart so the new shared object is loaded. This is a short downtime per deployment but is unavoidable. - Same‑Process Runtime
The plugin runs in the same process as Mattermost. A crash in the plugin can bring down the entire server. Keep the code simple and add defensive error handling. - Version Compatibility
Mattermost releases new API versions regularly. A plugin built againstv6.0may need recompilation forv6.1or later. Test against the target server version before deployment. - Regex Over‑Restriction
An overly strict pattern can frustrate users. Review the pattern with stakeholders before hard‑coding it.
6. Next Steps
1. Refine the Pattern – Add support for numeric prefixes or other project‑specific tokens.
2. Add Logging – Log each rejected attempt for audit purposes.
3. Expose a Config UI – Build a small admin page that lets users tweak the regex without editing files.
4. Automate Deployment – Use a CI pipeline that builds the plugin, runs unit tests, and pushes the .so to your server’s plugin directory.
5. Monitor Stability – Keep an eye on mattermost.log for panics or stack traces that might indicate plugin issues.
By moving naming enforcement into a lightweight plugin, you keep your channel list clean, give instant feedback to users, and avoid the overhead of manual moderation. Start with the minimal example above, iterate on the pattern, and extend the plugin as your team’s needs evolve.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.