# Custom Plugin not found after upload/activation

**URL:** <https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467>\
**Category:** Troubleshooting\
**Created:** [July 31, 2018, 10:55am UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467 "2018-07-31T10:55:08Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![karim](https://avatars.discourse-cdn.com/v4/letter/k/46a35a/32.png) [@karim](https://forum.mattermost.com/u/karim)\
**Post date:** [July 31, 2018, 10:55am UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/1 "2018-07-31T10:55:08Z")

</div>

Hi! I uploaded a custom plugin, but while trying to execute it by calling:  
http://{MatterMost\_URL}/plugins/{Plugin\_ID}  
i got 404 not found.

Notes:  
i am developing my code on windows and deploying on linux server (MatterMost server).  
so, i executed these commands before build:  
GOOS=linux  
GOARCH=amd64

Then build using:  
go build -o plugin.exe plugin.go  
///////////////////////////////////////////////////////////

plugin.go code:

package main

import (  
“net/http”  
“[github.com/mattermost/mattermost-server/plugin](http://github.com/mattermost/mattermost-server/plugin)”  
)

type HelloWorldPlugin struct {  
plugin.MattermostPlugin  
Enabled bool  
Secret string  
UserName string  
}

func (p \*HelloWorldPlugin) ServeHTTP(c \*plugin.Context, w http.ResponseWriter, r \*http.Request) {  
if !p.Enabled || p.Secret == “” || p.UserName == “” {  
http.Error(w, “This plugin is not configured.”, http.StatusForbidden)  
return  
}  
}

// This example demonstrates a plugin that handles HTTP requests which respond by greeting the  
// world.  
func main() {  
plugin.ClientMain(&HelloWorldPlugin{})  
}  
////////////////////////////////////////////////////////////////////////////////////////////////////////////

plugin.yaml:

id: com.mattermost.server-hello-world  
name: Server “Hello, world!”  
server:  
executable: ./plugin.exe  
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

---

<div class="post-metadata">

**Author:** ![haris](https://avatars.discourse-cdn.com/v4/letter/h/ccd318/32.png) [@haris](https://forum.mattermost.com/u/haris)\
**Post date:** [July 31, 2018, 5:43pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/2 "2018-07-31T17:43:06Z")

</div>

I am having the exact same problem.

---

<div class="post-metadata">

**Author:** ![amy.blais](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/amy.blais/32/7481_2.png) [@amy.blais](https://forum.mattermost.com/u/amy.blais)\
**Post date:** [July 31, 2018, 7:01pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/3 "2018-07-31T19:01:58Z")

</div>

Hi all! Thank you for reaching out.

I saw in another post that haris confirmed he is using v5.1 and the below config settings, @karim can you help confirm details of your environment and current config settings?

```auto
"PluginSettings": {
       "Enable": true,
       "EnableUploads": true,
       "Directory": "./plugins",
       "ClientDirectory": "./client/plugins",
       "Plugins": {},
       "PluginStates": {
           "com": {
               "Enable": true

```

---

<div class="post-metadata">

**Author:** ![haris](https://avatars.discourse-cdn.com/v4/letter/h/ccd318/32.png) [@haris](https://forum.mattermost.com/u/haris)\
**Post date:** [August 1, 2018, 3:19am UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/4 "2018-08-01T03:19:22Z")

</div>

@amy.blais Do let me know if I can help debug as well. Haven’t been able to get this to work yet.

Thanks!

---

<div class="post-metadata">

**Author:** ![haris](https://avatars.discourse-cdn.com/v4/letter/h/ccd318/32.png) [@haris](https://forum.mattermost.com/u/haris)\
**Post date:** [August 1, 2018, 3:52am UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/5 "2018-08-01T03:52:34Z")

</div>

I have mattermost installed on my local machine by following: [https://docs.mattermost.com/install/docker-local-machine.html#macos](https://docs.mattermost.com/install/docker-local-machine.html#macos)

Here is my mattermost and db version:

```auto
Mattermost Version: 5.1.0
Database Schema Version: 5.1.0
Database: mysql

```

Here is my docker installation’s OS and arch.

```auto
root@4bdee6a90b82:/mm/mattermost/plugins# uname -a
Linux 4bdee6a90b82 4.9.87-linuxkit-aufs #1 SMP Wed Mar 14 15:12:16 UTC 2018 x86_64 GNU/Linux

```

These are the tutorial steps I followed for building the executable plugin:

```auto
➜ my-plugin$ GOOS=linux GOARCH=amd64 go build -o plugin plugin.go
➜ my-plugin$ ls
plugin plugin.go plugin.yaml
➜ my-plugin$ file plugin
plugin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped
➜ my-plugin$ cat plugin.yaml
id: com.mattermost.server-hello-world
name: Server "Hello, world!"
server:
    executable: plugin

```

I uploaded the plugin on `http://localhost:8065/admin_console/plugins/management`.

This is how my file structure looks like:

```auto
root@4bdee6a90b82:/mm/mattermost$ ls client/plugins/
root@4bdee6a90b82:/mm/mattermost$ ls plugins/
com.mattermost.server-hello-world jira memes	zoom

```

---

<div class="post-metadata">

**Author:** ![karim](https://avatars.discourse-cdn.com/v4/letter/k/46a35a/32.png) [@karim](https://forum.mattermost.com/u/karim)\
**Post date:** [August 1, 2018, 10:50am UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/6 "2018-08-01T10:50:12Z")

</div>

Hi @amy.blais  
It is v4.9.1  
and yes this is similar to my config:  
“PluginSettings”: {  
“Enable”: true,  
“EnableUploads”: true,  
“Directory”: “./plugins”,  
“ClientDirectory”: “./client/plugins”,  
“Plugins”: {  
“jira”: {  
“enabled”: null,  
“secret”: null,  
“username”: null  
},  
“mattermost-profanity-filter”: {  
“censorcharacter”: “\*”,  
“rejectposts”: null  
},  
“zoom”: {  
“apikey”: null,  
“apisecret”: null,  
“webhooksecret”: null,  
“zoomapiurl”: null,  
“zoomurl”: null  
}  
},  
“PluginStates”: {  
“com.mattermost.server-hello-world”: {  
“Enable”: true  
},  
“jira”: {  
“Enable”: true  
},  
“mattermost-profanity-filter”: {  
“Enable”: true  
},  
“memes”: {  
“Enable”: true  
}  
}  
}

---

<div class="post-metadata">

**Author:** ![amy.blais](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/amy.blais/32/7481_2.png) [@amy.blais](https://forum.mattermost.com/u/amy.blais)\
**Post date:** [August 1, 2018, 1:56pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/7 "2018-08-01T13:56:09Z")

</div>

@crspeller / @jesse Would you be able to help with this one?

---

<div class="post-metadata">

**Author:** ![jesse](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/jesse/32/5168_2.png) [@jesse](https://forum.mattermost.com/u/jesse)\
**Post date:** [August 1, 2018, 2:25pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/8 "2018-08-01T14:25:32Z")

</div>

Hi @karim and @haris! The sample code you’ve posted suggests you’re writing a plugin for Mattermost 5.2 and later (e.g. using `ClientMain` and embedding `plugin.MattermostPlugin`). We’ve significantly overhauled plugins in Mattermost 5.2 as we prepare to take them out of beta, and as a result, plugins written for Mattermost 5.2 won’t work on Mattermost 5.1.

I suspect if you check your server logs, you’ll see an error from Mattermost about being unable to start up the plugin. That likely explains why your `ServeHTTP` endpoint isn’t being called.

Mattermost 5.2 is scheduled to be released on August 16th. While I encourage you to target plugin development for same, I can understand that you may not yet be in a position to upgrade when it is released. You can find an example plugin for Mattermost 5.1 at [https://github.com/mattermost/mattermost-server/blob/v5.1.0/plugin/example\_hello\_world\_test.go](https://github.com/mattermost/mattermost-server/blob/v5.1.0/plugin/example_hello_world_test.go) that should help you get unblocked.

---

<div class="post-metadata">

**Author:** ![haris](https://avatars.discourse-cdn.com/v4/letter/h/ccd318/32.png) [@haris](https://forum.mattermost.com/u/haris)\
**Post date:** [August 1, 2018, 2:32pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/9 "2018-08-01T14:32:41Z")

</div>

@jesse Oh! I believe both Karim and I took [https://developers.mattermost.com/extend/plugins/server/hello-world/](https://developers.mattermost.com/extend/plugins/server/hello-world/) to be the source of truth despite our version differences.

However, the logs does show that it was successfully able to activate the plugin though:  
`{"level":"info","ts":1533055427.971367,"caller":"app/plugin.go:208","msg":"Activated plugin","plugin_id":"com.mattermost.server-hello-world"}`

Probably that’s what threw us both off track thinking “We’ve done everything right and there’s something wrong with the doc”.

Will definitely keep the 5.2 upgrade in the pipeline. However, for the time being, at least I have to work with 5.1 since we’ve deployed and it is fuelling business logic in full swing. 🙂

Thanks for the plugin example for 5.1. Going to give that a shot right away and will report back on the thread with an update.

Thanks again @jesse, @amy.blais and @karim!

---

<div class="post-metadata">

**Author:** ![karim](https://avatars.discourse-cdn.com/v4/letter/k/46a35a/32.png) [@karim](https://forum.mattermost.com/u/karim)\
**Post date:** [August 1, 2018, 3:55pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/10 "2018-08-01T15:55:54Z")

</div>

Hi @jesse  
I tried with this code and same problem “plugin not found”

---

<div class="post-metadata">

**Author:** ![haris](https://avatars.discourse-cdn.com/v4/letter/h/ccd318/32.png) [@haris](https://forum.mattermost.com/u/haris)\
**Post date:** [August 1, 2018, 5:08pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/11 "2018-08-01T17:08:15Z")

</div>

@jesse To get it to work, I had to checkout the mattermost-server to the v5.1.0 tag.

Built it using `GOOS=linux GOARCH=amd64 go build -o plugin plugin.go`.

plugin.yaml looks like:

```auto
id: com.mattermost.server-hello-world
name: Server "Hello, world!"
server:
    executable: plugin

```

Uploaded the tar file and successfully activated plugin. The logs show `{"level":"info","ts":1533142981.2206817,"caller":"app/plugin.go:208","msg":"Activated plugin","plugin_id":"com.mattermost.server-hello-world"}`.

Restarted the docker mattermost-preview.

However, visiting `http://localhost:8065/plugins/com.mattermost.server-hello-world` still shows `404 page not found`.

Just to add to it, the zoom and meme plugins work fine on my local installation just in case you were wondering if this was because of a more general problem.

Anything I can do to help you help me further? Thanks!

---

<div class="post-metadata">

**Author:** ![haris](https://avatars.discourse-cdn.com/v4/letter/h/ccd318/32.png) [@haris](https://forum.mattermost.com/u/haris)\
**Post date:** [August 2, 2018, 4:32am UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/12 "2018-08-02T04:32:02Z")

</div>

> [@jesse](#):
>
> [https://github.com/mattermost/mattermost-server/blob/v5.1.0/plugin/example\_hello\_world\_test.go](https://github.com/mattermost/mattermost-server/blob/v5.1.0/plugin/example_hello_world_test.go)

Out of curiosity as well, in the 5.1 plugin example: [https://github.com/mattermost/mattermost-server/blob/v5.1.0/plugin/example\_hello\_world\_test.go](https://github.com/mattermost/mattermost-server/blob/v5.1.0/plugin/example_hello_world_test.go), where would the `fmt.Fprintf(w, "Hello, world!")` be printed? I assume it is supposed to show up on the logs?

---

<div class="post-metadata">

**Author:** ![jesse](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/jesse/32/5168_2.png) [@jesse](https://forum.mattermost.com/u/jesse)\
**Post date:** [August 2, 2018, 2:28pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/13 "2018-08-02T14:28:38Z")

</div>

Hi Haris!

Change your `plugin.yaml` to specify a `backend` key. In Mattermost 5.2, this was changed to be consistent with the rest of the architecture and use the key `server`, but you’ll need to use the old key for now:

```auto
id: com.mattermost.server-hello-world
name: Server "Hello, world!"
backend:
    executable: plugin

```

With that change, I can compile the code and get the desired output from the HTTP endpoint. The `fmt.Fprintf` takes a `io.Writer` as its first parameter – in this case, the `http.ResponseWriter`, so the “Hello World!” is written as the response to the HTTP request.

@karim, I suspect there’s an issue in how your plugin is being bundled and initialized. I might suggest taking a look at [https://github.com/mattermost/mattermost-developer-documentation/tree/plugins-v5.1.0/site/content/extend/plugins](https://github.com/mattermost/mattermost-developer-documentation/tree/plugins-v5.1.0/site/content/extend/plugins) (tagged to the 5.1.0 version) to see if there’s something there that might help. Or if you can post a more detailed breakdown of your plugin bundling strategy, I can try to help.

With Mattermost 5.2, we’ve also launched [https://github.com/mattermost/mattermost-plugin-sample](https://github.com/mattermost/mattermost-plugin-sample) and [https://github.com/mattermost/mattermost-plugin-demo](https://github.com/mattermost/mattermost-plugin-demo) to better illustrate all of these details, but of course those won’t help you until you can upgrade 🙂

---

<div class="post-metadata">

**Author:** ![haris](https://avatars.discourse-cdn.com/v4/letter/h/ccd318/32.png) [@haris](https://forum.mattermost.com/u/haris)\
**Post date:** [August 2, 2018, 5:47pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/14 "2018-08-02T17:47:42Z")

</div>

> [@haris](#):
>
> [https://github.com/mattermost/mattermost-server/blob/v5.1.0/plugin/example\_hello\_world\_test.go](https://github.com/mattermost/mattermost-server/blob/v5.1.0/plugin/example_hello_world_test.go)

Hey @jesse,

Thanks a ton for your patience.

I did as you suggested, built the plugin, tarred and uploaded it. Upon clicking activate however, it gave me:  
`This plugin failed to start. Check your system logs for errors.`

The logs had this to show:

```auto
# {"level":"error","ts":1533231099.1921234,"caller":"app/plugin.go:158","msg":"Plugin failed to activate","plugin_id":"com.mattermost.server-hello-world","err":"unable to start plugin: com.mattermost.server-hello-world: fork/exec plugins/com.mattermost.server-hello-world/plugin: permission denied"}
# {"level":"error","ts":1533231100.1951332,"caller":"rpcplugin/supervisor.go:92","msg":"Plugin terminated unexpectedly","plugin_id":"com.mattermost.server-hello-world"}
# {"level":"error","ts":1533231102.1994798,"caller":"rpcplugin/supervisor.go:92","msg":"Plugin terminated unexpectedly","plugin_id":"com.mattermost.server-hello-world"}
# {"level":"error","ts":1533231107.2012076,"caller":"rpcplugin/supervisor.go:96","msg":"Plugin shutdown","plugin_id":"com.mattermost.server-hello-world","max_process_restarts":3,"error":"plugin terminated unexpectedly too many times"}

```

Googling hinted about the “executable” bit being set. So I tried a `chmod +x` on the built `plugin`. However, trying to `Activate` that after uploading gave me the error:

```auto
# {"level":"error","ts":1533230635.717955,"caller":"app/plugin.go:158","msg":"Plugin failed to activate","plugin_id":"com.mattermost.server-hello-world","err":"unable to start plugin: com.mattermost.server-hello-world: fork/exec plugins/com.mattermost.server-hello-world/plugin: exec format error"}

```

The troubleshooting tips at [Redirect](https://docs.mattermost.com/administration/plugins.html#troubleshooting) are for “failing uploads”, but my upload works fine and it is the `Activate` that is failing.

However, the funny part is, I tried changing the `yaml` file from `backend` back to `server`, built, uploaded and it got activated without any problem! The logs had:

```auto
{"level":"info","ts":1533231385.0844607,"caller":"app/plugin.go:208","msg":"Activated plugin","plugin_id":"com.mattermost.server-hello-world"}

```

Unfortunately, visiting `http://localhost:8065/plugins/com.mattermost.server-hello-world` still shows `404 not found`.

Just to confirm, I am indeed running 5.1:  
 ![55%20PM](https://us1.discourse-cdn.com/flex020/uploads/mattermost/original/2X/e/e0690baf1836b6227cea9e51c61019e9f3cff1cb.png)

Any hints that I could try out or any other piece of information that I can give you which would let you help me?

Thanks again!

---

<div class="post-metadata">

**Author:** ![jesse](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/jesse/32/5168_2.png) [@jesse](https://forum.mattermost.com/u/jesse)\
**Post date:** [August 2, 2018, 9:29pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/15 "2018-08-02T21:29:17Z")

</div>

Happy to help, @haris! The `Activated plugin` message is misleading, because the server is seeing a plugin with basically no backend or frontend component, and “activates” nothing successfully. I’ll make sure we fix this in an upcoming release to avoid the ambiguity.

chmod u+x shouldn’t have been necessary – go is supposed to set the executable bit correctly itself. I presume your server is actually running on Linux (and not Darwin or Windows)?

The only other thing is to make sure the plugin.go file is actually using the `main` package. The example can’t show this, given the way godoc works, but here’s a working copy:

```auto
package main

import (
	"fmt"
	"net/http"

	"github.com/mattermost/mattermost-server/plugin/rpcplugin"
)

type HelloWorldPlugin struct{}

func (p *HelloWorldPlugin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, world!")
}

// This example demonstrates a plugin that handles HTTP requests which respond by greeting the
// world.
func main() {
	rpcplugin.Main(&HelloWorldPlugin{})
}

```

---

<div class="post-metadata">

**Author:** ![haris](https://avatars.discourse-cdn.com/v4/letter/h/ccd318/32.png) [@haris](https://forum.mattermost.com/u/haris)\
**Post date:** [August 3, 2018, 4:37am UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/16 "2018-08-03T04:37:12Z")

</div>

@jesse That did it! 🙂

I believe I had tried the `package main` before, but had `func Example_helloWorld` instead of `func main`. And while trying to build, that had given me errors of the sort:

```auto
runtime.main_main·f: relocation target main.main not defined
runtime.main_main·f: undefined: "main.main"

```

I guess my lack of Go knowledge coupled with the slightly ambiguous plugin examples is what ended up here.

But all’s well that ends well. Thanks a ton again @jesse and @amy.blais.

@karim, and for anyone else who ends up here, here is my setup for Mattermost 5.1:

`plugin.go`:

```auto
package main

import (
	"fmt"
	"net/http"

	"github.com/mattermost/mattermost-server/plugin/rpcplugin"
)

type HelloWorldPlugin struct{}

func (p *HelloWorldPlugin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, world!")
}

// This example demonstrates a plugin that handles HTTP requests which respond by greeting the
// world.
func main() {
	rpcplugin.Main(&HelloWorldPlugin{})
}

```

`plugin.yaml`

```auto
id: com.mattermost.server-hello-world
name: Server "Hello, world!"
backend:
    executable: plugin

```

Built using (for Linux):

```auto
GOOS=linux GOARCH=amd64 go build -o plugin plugin.go

```

Tar it:

```auto
tar -czvf plugin.tar.gz plugin plugin.yaml

```

Upload it on mattermost, and activate it.  
You should be able to see `Hello, world!` on [http://localhost:8065/plugins/com.mattermost.server-hello-world](http://localhost:8065/plugins/com.mattermost.server-hello-world).

@jesse On a side note, if there’s anything you want me to try out to get feedback on and / or improve documentation anywhere, do let me know. I’ve enjoyed integrating it into our workflow and with the Slack outages that happen, I see MM quickly becoming and integral part our business.

Cheers!

---

<div class="post-metadata">

**Author:** ![jesse](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.mattermost.com/jesse/32/5168_2.png) [@jesse](https://forum.mattermost.com/u/jesse)\
**Post date:** [August 3, 2018, 7:07pm UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/17 "2018-08-03T19:07:10Z")

</div>

Thanks for confirming @haris, and for sticking in there 🙂

We discussed internally as a team how we wanted to handle precisely your use case, especially given the beta nature of plugins as they were. I think we can do more here to improve the documentation experience, probably starting with getting the old documentation available on [developers.mattermost.com](http://developers.mattermost.com). I’ll bring this up to see how we can improve things for you and those who follow after you!

---

<div class="post-metadata">

**Author:** ![karim](https://avatars.discourse-cdn.com/v4/letter/k/46a35a/32.png) [@karim](https://forum.mattermost.com/u/karim)\
**Post date:** [August 5, 2018, 10:29am UTC](https://forum.mattermost.com/t/custom-plugin-not-found-after-upload-activation/5467/18 "2018-08-05T10:29:11Z")

</div>

Thanks @jesse and @haris, it is working now 🙂
