diff --git a/controller/controller.go b/controller/controller.go
index d9118331755a1a9d3d51391218c1c35347cdfad3..d16fd4bf1d5fdba44f7ddde102a0b6a5dd3b43ff 100644
--- a/controller/controller.go
+++ b/controller/controller.go
@@ -392,7 +392,7 @@ func shutdown() error {
 		}
 		for _, plugin := range plugins {
 			log.Info("Defer: ", plugin.Manifest().Name)
-			plugin.GetClient().Kill()
+			plugin.Close()
 			log.Info("Defer - exited: ", plugin.GetClient().Exited())
 		}
 		coreLock.Unlock()
diff --git a/controller/interfaces/plugin/plugin.go b/controller/interfaces/plugin/plugin.go
index f61bda8a8ec589486a6452141d4e07727790e2c3..e51743309a2cff64ada5a8d5f9574646ef6281b5 100644
--- a/controller/interfaces/plugin/plugin.go
+++ b/controller/interfaces/plugin/plugin.go
@@ -46,6 +46,7 @@ type Plugin interface {
 	Ping() error
 	Restart() error
 	Close()
+	Remove() error
 	shared.DeviceModel
 }
 
diff --git a/controller/northbound/server/networkElement.go b/controller/northbound/server/networkElement.go
index 7455a040c5b6403cd1c4f0804ddf103cf4a552a8..473a2fe417364ea7d195aa9999298e60878fe24a 100644
--- a/controller/northbound/server/networkElement.go
+++ b/controller/northbound/server/networkElement.go
@@ -723,32 +723,43 @@ func (n *NetworkElementServer) addMne(ctx context.Context, name string, opt *tpb
 
 	mne, err := nucleus.NewNetworkElement(name, networkElementID, opt, pndID, plugin, conflict.Metadata{ResourceVersion: 0})
 	if err != nil {
+		plugin.Remove()
 		return uuid.Nil, err
 	}
 
 	if mne.IsTransportValid() {
 		resp, err := n.getPath(ctx, mne, "/")
 		if err != nil {
+			plugin.Remove()
 			return uuid.Nil, err
 		}
 
 		err = mne.ProcessResponse(resp)
 		if err != nil {
+			plugin.Remove()
 			return uuid.Nil, err
 		}
 
 		err = n.mneService.Add(mne)
 		if err != nil {
+			plugin.Remove()
 			return uuid.Nil, err
 		}
 
 		err = n.pluginService.Add(plugin)
 		if err != nil {
+			if err := plugin.Remove(); err != nil {
+				return uuid.Nil, status.Errorf(codes.Internal, "failed to clean up plugin: ", err)
+			}
+			if err := n.mneService.Delete(mne); err != nil {
+				return uuid.Nil, status.Errorf(codes.Internal, "failed to clean up device: ", err)
+			}
 			return uuid.Nil, err
 		}
 
 		n.networkElementWatchter.SubscribeToNetworkElement(mne, config.GetGnmiSubscriptionPaths(), nil)
 	} else {
+		plugin.Remove()
 		return uuid.Nil, status.Errorf(codes.InvalidArgument, "invalid transport data provided")
 	}
 
diff --git a/controller/nucleus/plugin.go b/controller/nucleus/plugin.go
index 032c30ed4136f8741ff6a13de47b19f5a4a3275c..1709217e489ab574b518e4c2354d569815e44caf 100644
--- a/controller/nucleus/plugin.go
+++ b/controller/nucleus/plugin.go
@@ -3,6 +3,7 @@ package nucleus
 import (
 	"encoding/json"
 	"fmt"
+	"os"
 	"os/exec"
 	"path/filepath"
 
@@ -129,6 +130,15 @@ func (p *Plugin) ReattachConfig() *hcplugin.ReattachConfig {
 	return p.client.ReattachConfig()
 }
 
+// Remove ensures that the Plugin is killed and the corresponding files are
+// removed.
+func (p *Plugin) Remove() error {
+	// stop the running plugins process
+	p.Close()
+	// remove the plugins folder
+	return os.RemoveAll(p.ExecPath())
+}
+
 // State returns the current state of the plugin.
 // Different states of the plugin can be:
 //   - created
@@ -165,6 +175,7 @@ func (p *Plugin) Restart() error {
 
 // Close ends the execution of the plugin.
 func (p *Plugin) Close() {
+	// end the plugin process
 	p.client.Kill()
 }
 
diff --git a/controller/nucleus/pluginService.go b/controller/nucleus/pluginService.go
index 4b041518174b082d70590b5f2dfdfeb0cdf3c3bf..3a1319efdc90595c9d3f6e3249d5ff7fd26250b3 100644
--- a/controller/nucleus/pluginService.go
+++ b/controller/nucleus/pluginService.go
@@ -106,7 +106,7 @@ func (s *PluginService) Delete(pluginToDelete plugin.Plugin) error {
 	}
 
 	// stop the plugin
-	pluginToDelete.GetClient().Kill()
+	pluginToDelete.Close()
 
 	if err := s.eventService.PublishEvent(PluginEventTopic, event.NewDeleteEvent(pluginToDelete.ID())); err != nil {
 		log.Error(err)