diff --git a/cmd/opm/main.go b/cmd/opm/main.go
index 963467d20..550adad8c 100644
--- a/cmd/opm/main.go
+++ b/cmd/opm/main.go
@@ -5,11 +5,13 @@ import (
 
 	"github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
+	utilerrors "k8s.io/apimachinery/pkg/util/errors"
 
 	"github.com/operator-framework/operator-registry/cmd/opm/alpha"
 	"github.com/operator-framework/operator-registry/cmd/opm/index"
 	"github.com/operator-framework/operator-registry/cmd/opm/registry"
 	"github.com/operator-framework/operator-registry/cmd/opm/version"
+	registrylib "github.com/operator-framework/operator-registry/pkg/registry"
 )
 
 func main() {
@@ -35,6 +37,18 @@ func main() {
 	}
 
 	if err := rootCmd.Execute(); err != nil {
+		agg, ok := err.(utilerrors.Aggregate)
+		if !ok {
+			os.Exit(1)
+		}
+		for _, e := range agg.Errors() {
+			if _, ok := e.(registrylib.BundleImageAlreadyAddedErr); ok {
+				os.Exit(2)
+			}
+			if _, ok := e.(registrylib.PackageVersionAlreadyAddedErr); ok {
+				os.Exit(3)
+			}
+		}
 		os.Exit(1)
 	}
 }
diff --git a/pkg/lib/indexer/indexer.go b/pkg/lib/indexer/indexer.go
index fb2a5ebc4..e30a48a1d 100644
--- a/pkg/lib/indexer/indexer.go
+++ b/pkg/lib/indexer/indexer.go
@@ -85,6 +85,7 @@ func (i ImageIndexer) AddToIndex(request AddToIndexRequest) error {
 	// Add the bundles to the registry
 	err = i.RegistryAdder.AddToRegistry(addToRegistryReq)
 	if err != nil {
+		i.Logger.WithError(err).Debugf("unable to add bundle to registry")
 		return err
 	}
 
@@ -222,7 +223,6 @@ func (i ImageIndexer) PruneFromIndex(request PruneFromIndexRequest) error {
 	return nil
 }
 
-
 // extractDatabase sets a temp directory for unpacking an image
 func (i ImageIndexer) extractDatabase(buildDir, fromIndex string) (string, error) {
 	tmpDir, err := ioutil.TempDir("./", tmpDirPrefix)
diff --git a/pkg/lib/registry/registry.go b/pkg/lib/registry/registry.go
index e0899722e..618e7040a 100644
--- a/pkg/lib/registry/registry.go
+++ b/pkg/lib/registry/registry.go
@@ -5,16 +5,16 @@ import (
 	"crypto/x509"
 	"database/sql"
 	"fmt"
-	"github.com/operator-framework/operator-registry/pkg/containertools"
-	"github.com/operator-framework/operator-registry/pkg/image/execregistry"
 	"io/ioutil"
 	"os"
 
 	"github.com/sirupsen/logrus"
 	utilerrors "k8s.io/apimachinery/pkg/util/errors"
 
+	"github.com/operator-framework/operator-registry/pkg/containertools"
 	"github.com/operator-framework/operator-registry/pkg/image"
 	"github.com/operator-framework/operator-registry/pkg/image/containerdregistry"
+	"github.com/operator-framework/operator-registry/pkg/image/execregistry"
 	"github.com/operator-framework/operator-registry/pkg/registry"
 	"github.com/operator-framework/operator-registry/pkg/sqlite"
 )
@@ -34,8 +34,6 @@ type AddToRegistryRequest struct {
 }
 
 func (r RegistryUpdater) AddToRegistry(request AddToRegistryRequest) error {
-	var errs []error
-
 	db, err := sql.Open("sqlite3", request.InputDatabase)
 	if err != nil {
 		return err
@@ -96,16 +94,17 @@ func (r RegistryUpdater) AddToRegistry(request AddToRegistryRequest) error {
 	}
 
 	if err := populate(context.TODO(), dbLoader, graphLoader, dbQuerier, reg, simpleRefs, request.Mode); err != nil {
-		err = fmt.Errorf("error loading bundle from image: %s", err)
+		r.Logger.Debugf("unable to populate database: %s", err)
+
 		if !request.Permissive {
 			r.Logger.WithError(err).Error("permissive mode disabled")
-			errs = append(errs, err)
+			return err
 		} else {
 			r.Logger.WithError(err).Warn("permissive mode enabled")
 		}
 	}
 
-	return utilerrors.NewAggregate(errs) // nil if no errors
+	return nil
 }
 
 func populate(ctx context.Context, loader registry.Load, graphLoader registry.GraphLoader, querier registry.Query, reg image.Registry, refs []image.Reference, mode registry.Mode) error {
diff --git a/pkg/registry/populator.go b/pkg/registry/populator.go
index 7c6dbd95c..8e3e2eb5a 100644
--- a/pkg/registry/populator.go
+++ b/pkg/registry/populator.go
@@ -63,7 +63,50 @@ func (i *DirectoryPopulator) Populate(mode Mode) error {
 	return nil
 }
 
+func (i *DirectoryPopulator) globalSanityCheck(imagesToAdd []*ImageInput) error {
+	var errs []error
+	images := make(map[string]struct{})
+	for _, image := range imagesToAdd {
+		images[image.bundle.BundleImage] = struct{}{}
+	}
+
+	for _, image := range imagesToAdd {
+		bundlePaths, err := i.querier.GetBundlePathsForPackage(context.TODO(), image.bundle.Package)
+		if err != nil {
+			// Assume that this means that the bundle is empty
+			// Or that this is the first time the package is loaded.
+			return nil
+		}
+		for _, bundlePath := range bundlePaths {
+			if _, ok := images[bundlePath]; ok {
+				errs = append(errs, BundleImageAlreadyAddedErr{ErrorString: fmt.Sprintf("Bundle %s already exists", image.bundle.BundleImage)})
+				continue
+			}
+		}
+		for _, channel := range image.bundle.Channels {
+			bundle, err := i.querier.GetBundle(context.TODO(), image.bundle.Package, channel, image.bundle.csv.GetName())
+			if err != nil {
+				// Assume that if we can not find a bundle for the package, channel and or CSV Name that this is safe to add
+				continue
+			}
+			if bundle != nil {
+				// raise error that this package + channel + csv combo is already in the db
+				errs = append(errs, PackageVersionAlreadyAddedErr{ErrorString: "Bundle already added that provides package and csv"})
+				break
+			}
+		}
+	}
+
+	return utilerrors.NewAggregate(errs)
+}
+
 func (i *DirectoryPopulator) loadManifests(imagesToAdd []*ImageInput, mode Mode) error {
+	// global sanity checks before insertion
+	err := i.globalSanityCheck(imagesToAdd)
+	if err != nil {
+		return err
+	}
+
 	switch mode {
 	case ReplacesMode:
 		// TODO: This is relatively inefficient. Ideally, we should be able to use a replaces
diff --git a/pkg/registry/populator_test.go b/pkg/registry/populator_test.go
index 85e515018..9552e81af 100644
--- a/pkg/registry/populator_test.go
+++ b/pkg/registry/populator_test.go
@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"math/rand"
 	"os"
+	"reflect"
 	"testing"
 	"time"
 
@@ -16,6 +17,8 @@ import (
 	"github.com/operator-framework/operator-registry/pkg/image"
 	"github.com/operator-framework/operator-registry/pkg/registry"
 	"github.com/operator-framework/operator-registry/pkg/sqlite"
+
+	utilerrors "k8s.io/apimachinery/pkg/util/errors"
 )
 
 func init() {
@@ -246,6 +249,7 @@ func TestImageLoading(t *testing.T) {
 		addImage     img
 		wantPackages []*registry.Package
 		wantErr      bool
+		err          error
 	}{
 		{
 			name: "OneChannel/AddBundleToTwoChannels",
@@ -386,6 +390,76 @@ func TestImageLoading(t *testing.T) {
 			},
 			wantErr: false,
 		},
+		{
+			name: "AddBundleAlreadyExists",
+			initImages: []img{
+				{
+					// this is in the "preview" channel
+					ref: image.SimpleReference("quay.io/prometheus/operator:0.14.0"),
+					dir: "../../bundles/prometheus.0.14.0",
+				},
+			},
+			addImage: img{
+				//Adding same bundle different bundle
+				ref: image.SimpleReference("quay.io/prometheus/operator-test:testing"),
+				dir: "../../bundles/prometheus.0.14.0",
+			},
+			wantPackages: []*registry.Package{
+				{
+					Name:           "prometheus",
+					DefaultChannel: "stable",
+					Channels: map[string]registry.Channel{
+						"preview": {
+							Head: registry.BundleKey{
+								BundlePath: "quay.io/prometheus/operator:0.14.0",
+								Version:    "0.14.0",
+								CsvName:    "prometheusoperator.0.14.0",
+							},
+							Nodes: map[registry.BundleKey]map[registry.BundleKey]struct{}{
+								{BundlePath: "quay.io/prometheus/operator:0.14.0", Version: "0.14.0", CsvName: "prometheusoperator.0.14.0"}: {},
+							},
+						},
+					},
+				},
+			},
+			wantErr: true,
+			err:     registry.PackageVersionAlreadyAddedErr{},
+		},
+		{
+			name: "AddExactBundleAlreadyExists",
+			initImages: []img{
+				{
+					// this is in the "preview" channel
+					ref: image.SimpleReference("quay.io/prometheus/operator:0.14.0"),
+					dir: "../../bundles/prometheus.0.14.0",
+				},
+			},
+			addImage: img{
+				// Add the same package
+				ref: image.SimpleReference("quay.io/prometheus/operator:0.14.0"),
+				dir: "../../bundles/prometheus.0.14.0",
+			},
+			wantPackages: []*registry.Package{
+				{
+					Name:           "prometheus",
+					DefaultChannel: "stable",
+					Channels: map[string]registry.Channel{
+						"preview": {
+							Head: registry.BundleKey{
+								BundlePath: "quay.io/prometheus/operator:0.14.0",
+								Version:    "0.14.0",
+								CsvName:    "prometheusoperator.0.14.0",
+							},
+							Nodes: map[registry.BundleKey]map[registry.BundleKey]struct{}{
+								{BundlePath: "quay.io/prometheus/operator:0.14.0", Version: "0.14.0", CsvName: "prometheusoperator.0.14.0"}: {},
+							},
+						},
+					},
+				},
+			},
+			wantErr: true,
+			err:     registry.BundleImageAlreadyAddedErr{},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -411,7 +485,12 @@ func TestImageLoading(t *testing.T) {
 				graphLoader,
 				query,
 				map[image.Reference]string{tt.addImage.ref: tt.addImage.dir})
-			require.NoError(t, add.Populate(registry.ReplacesMode))
+			err = add.Populate(registry.ReplacesMode)
+			if tt.wantErr {
+				require.True(t, checkAggErr(err, tt.err))
+				return
+			}
+			require.NoError(t, err)
 
 			for _, p := range tt.wantPackages {
 				graphLoader, err := sqlite.NewSQLGraphLoaderFromDB(db)
@@ -426,6 +505,18 @@ func TestImageLoading(t *testing.T) {
 	}
 }
 
+func checkAggErr(aggErr, wantErr error) bool {
+	if a, ok := aggErr.(utilerrors.Aggregate); ok {
+		for _, e := range a.Errors() {
+			if reflect.TypeOf(e).String() == reflect.TypeOf(wantErr).String() {
+				return true
+			}
+		}
+		return false
+	}
+	return reflect.TypeOf(aggErr).String() == reflect.TypeOf(wantErr).String()
+}
+
 func TestQuerierForDependencies(t *testing.T) {
 	logrus.SetLevel(logrus.DebugLevel)
 	db, cleanup := CreateTestDb(t)
diff --git a/pkg/registry/types.go b/pkg/registry/types.go
index e6f5afe29..0cf5e83eb 100644
--- a/pkg/registry/types.go
+++ b/pkg/registry/types.go
@@ -14,6 +14,24 @@ var (
 	ErrPackageNotInDatabase = errors.New("Package not in database")
 )
 
+// BundleImageAlreadyAddedErr is an error that describes a bundle is already added
+type BundleImageAlreadyAddedErr struct {
+	ErrorString string
+}
+
+func (e BundleImageAlreadyAddedErr) Error() string {
+	return e.ErrorString
+}
+
+// PackageVersionAlreadyAddedErr is an error that describes that a bundle that is already in the databse that provides this package and version
+type PackageVersionAlreadyAddedErr struct {
+	ErrorString string
+}
+
+func (e PackageVersionAlreadyAddedErr) Error() string {
+	return e.ErrorString
+}
+
 const (
 	GVKType     = "olm.gvk"
 	PackageType = "olm.package"