Grafana Plugin Troubleshooting Guide
Common issues and solutions for Grafana plugin development (v12.x+).
Plugin Not Appearing
Symptoms
- Plugin doesn't show in Grafana's plugin list
- "Plugin not found" errors
Solutions
Check plugin.json
# Verify plugin.json is valid JSON cat dist/plugin.json | jq . # Check required fields jq '.id, .type, .name' dist/plugin.jsonVerify dist folder structure
ls -la dist/ # Should contain: # - plugin.json # - module.js # - img/ folder (optional)Check unsigned plugin setting
# grafana.ini or GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS env var [plugins] allow_loading_unsigned_plugins = your-plugin-idRestart Grafana
docker compose restart grafana # or systemctl restart grafana-serverCheck Grafana logs
docker compose logs grafana | grep -i plugin
Build Errors
TypeScript Errors
# Check TypeScript version compatibility
npm ls typescript
# Update @grafana packages to matching versions
npm update @grafana/data @grafana/ui @grafana/runtimeWebpack Errors
# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
# Clear build cache
rm -rf dist .cache
npm run buildGo Backend Build Errors
# Update Go SDK
go get -u github.com/grafana/grafana-plugin-sdk-go
go mod tidy
# Check Go version (1.21+ required)
go version
# Build with verbose output
mage -v build:linuxBackend Plugin Not Working
Symptoms
- "Plugin failed to load" in Grafana
- Backend health check fails
- No data returned from queries
Solutions
Check binary exists
ls -la dist/gpx_* # Should have executable binaries for target platformsVerify plugin.json backend settings
{ "backend": true, "executable": "gpx_yourplugin" }Check binary permissions
chmod +x dist/gpx_*Check Grafana logs for backend errors
docker compose logs grafana 2>&1 | grep -i "yourplugin"Test health check manually
curl -X POST http://admin:admin@localhost:3000/api/ds/query \ -H "Content-Type: application/json" \ -d '{"queries":[{"datasource":{"type":"your-datasource","uid":"xxx"}}]}'
Data Source Connection Issues
Authentication Errors
Check secureJsonData storage
- API keys should use
secureJsonData, notjsonData - Verify onReset handler clears the field
- API keys should use
CORS issues
// In plugin.json routes { "routes": [{ "path": "api", "url": "https://api.example.com", "headers": [ {"name": "Authorization", "content": "Bearer {{.SecureJsonData.apiKey}}"} ] }] }Backend proxy not configured
- For frontend data sources, use
getBackendSrv().fetch() - Configure routes in plugin.json for proxy
- For frontend data sources, use
No Data Returned
Check time range handling
// Ensure time range is passed to API const from = options.range.from.valueOf(); const to = options.range.to.valueOf();Verify data frame format
// Time field must be first or explicitly typed const frame = new MutableDataFrame({ fields: [ { name: 'Time', type: FieldType.time, values: [...] }, { name: 'Value', type: FieldType.number, values: [...] }, ], });Check console for errors
- Open browser DevTools → Console
- Look for network errors in Network tab
Docker Development Issues
Volume Mount Problems
# Verify mount is correct
docker compose exec grafana ls -la /var/lib/grafana/plugins/
# Check compose file volume syntax
volumes:
- ./dist:/var/lib/grafana/plugins/your-plugin-idContainer Won't Start
# Check for port conflicts
lsof -i :3000
# Remove orphan containers
docker compose down --remove-orphans
docker compose up -dChanges Not Reflecting
# Ensure dev mode is running
npm run dev
# Hard refresh browser
# Cmd+Shift+R (Mac) or Ctrl+Shift+R (Windows/Linux)
# Restart Grafana to reload plugin
docker compose restart grafanaPanel Plugin Issues
Panel Shows "No Data"
Check data link in panel settings
- Ensure data source is selected
- Run a test query
Handle empty data gracefully
if (!data.series || data.series.length === 0) { return <div>No data available</div>; }
Options Not Saving
Check option path names
- Paths must match TypeScript interface
- Use dot notation for nested:
nested.option
Verify default values
.addTextInput({ path: 'text', defaultValue: 'default', // Must be valid for the type })
Visualization Not Updating
Check React dependencies
// Use useEffect with proper dependencies useEffect(() => { // Update visualization }, [data, options, width, height]);Avoid mutating props
- Create new objects when transforming data
- Use spread operators or Object.assign
Signing and Publishing
Signing Errors
# Check plugin ID format
# Must be: <org>-<name>-<type>
# Example: myorg-mypanel-panel
# Verify Grafana Cloud credentials
export GRAFANA_ACCESS_POLICY_TOKEN=your-token
npx @grafana/sign-plugin@latestCatalog Submission Issues
Ensure all required files exist
- README.md
- LICENSE
- CHANGELOG.md
- Screenshots in img/
Validate plugin.json
- All info fields populated
- Valid semver version
- Correct grafanaDependency
Performance Issues
Slow Panel Rendering
Memoize expensive calculations
const processedData = useMemo(() => { return transformData(data); }, [data]);Use virtualization for large datasets
- Consider react-window or react-virtualized
Debounce option changes
const debouncedOnChange = useDebouncedCallback(onChange, 300);
Memory Leaks
Clean up subscriptions
useEffect(() => { const subscription = observable.subscribe(); return () => subscription.unsubscribe(); }, []);Cancel pending requests
useEffect(() => { const controller = new AbortController(); fetch(url, { signal: controller.signal }); return () => controller.abort(); }, [url]);
Getting Help
- Check official documentation: https://grafana.com/developers/plugin-tools/
- Grafana Community Forums: https://community.grafana.com/
- GitHub Issues: https://github.com/grafana/plugin-tools/issues
- Ask the grafana-plugin-expert agent for SDK-specific guidance