diff --git a/error/error.go b/error/error.go
new file mode 100644
index 0000000..c30096b
--- /dev/null
+++ b/error/error.go
@@ -0,0 +1,344 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package error
+
+/*  Cordctl error classes
+
+	The basic idea is to throw specific error classes, so it's easier to test for them rather than doing string
+	comparisons or other ad hoc mechanisms for determining the type of error. This decouples the human
+	readable text of an error from programmatic testing of error type.
+
+	We differentiate between errors that we want to generate brief output, such as for example a
+	user mistyping a model name, versus errors that we want to generate additional context. This prevents
+	overwhelming a user with voluminous output for a simple mistake. A command-line option may be provided
+	to force full error output should it be desired.
+
+	Additionally, an added benefit is ease of maintenance and localisation, by locating all error text
+	in one place.
+
+	To return an error, for example:
+
+		return WithStackTrace(&ChecksumMismatchError{Actual: "123", Expected: "456"})
+
+	To check to see if a specific error was returned, either of the following are acceptable:
+
+		_, ok := err.(*ChecksumMismatchError)
+		...
+
+		switch err.(type) {
+		case *ChecksumMismatchError:
+        ...
+*/
+
+import (
+	"bytes"
+	"fmt"
+	go_errors "github.com/go-errors/errors"
+	"os"
+	"runtime"
+	"strings"
+)
+
+const (
+	MaxStackDepth = 50
+)
+
+// Prefix applied to all error messages. Initialized in module init() function from os.Args[0]
+var prefix string
+
+/* CordCtlError is the interface for errors created by cordctl.
+ *    ShouldDumpStack()
+ *        Returns false for well-understood problems such as invalid user input where a brief error message is sufficient
+ *		  Returns true for poorly-understood / unexpected problems where a full dump context may be useful
+ *    Stack()
+ *        Returns a string containing the stack trace where the error occurred
+ *        Only useful if WithStackTrace() was called on the error
+ */
+
+type CordCtlError interface {
+	error
+	ShouldDumpStack() bool
+	Stack() string
+	AddStackTrace(skip int)
+}
+
+/* BaseError supports attaching stack traces to errors
+ *    Borrowed the technique from github.com/go-errors. Decided against using go-errors directly since it requires
+ *    wrapping our error classes. Instead, incorporated the stack trace directly into our error class.
+ */
+
+type BaseError struct {
+	stack  []uintptr
+	frames []go_errors.StackFrame
+}
+
+func (f *BaseError) AddStackTrace(skip int) {
+	stack := make([]uintptr, MaxStackDepth)
+	length := runtime.Callers(2+skip, stack[:])
+	f.stack = stack[:length]
+}
+
+func (f *BaseError) Stack() string {
+	buf := bytes.Buffer{}
+
+	for _, frame := range f.StackFrames() {
+		buf.WriteString(frame.String())
+	}
+
+	return string(buf.Bytes())
+}
+
+func (f *BaseError) StackFrames() []go_errors.StackFrame {
+	if f.frames == nil {
+		f.frames = make([]go_errors.StackFrame, len(f.stack))
+
+		for i, pc := range f.stack {
+			f.frames[i] = go_errors.NewStackFrame(pc)
+		}
+	}
+
+	return f.frames
+}
+
+// ***************************************************************************
+// UserError is composed into Errors that are due to user input
+
+type UserError struct {
+	BaseError
+}
+
+func (f UserError) ShouldDumpStack() bool {
+	return false
+}
+
+// **************************************************************************
+// TransferError is composed into Errors that are due to failures in transfers
+
+type TransferError struct {
+	BaseError
+}
+
+func (f TransferError) ShouldDumpStack() bool {
+	return false
+}
+
+// ***************************************************************************
+// UnexpectedError is things that we don't expect to happen. They should
+// generate maximum error context, to provide useful information for developer
+// diagnosis.
+
+type UnexpectedError struct {
+	BaseError
+}
+
+func (f UnexpectedError) ShouldDumpStack() bool {
+	return true
+}
+
+// ***************************************************************************
+// Specific error classes follow
+
+// Checksum mismatch when downloading or uploading a file
+type ChecksumMismatchError struct {
+	TransferError
+	Name     string // (optional) Name of file
+	Expected string
+	Actual   string
+}
+
+func (f ChecksumMismatchError) Error() string {
+	if f.Name != "" {
+		return fmt.Sprintf("%s %s: checksum mismatch (actual=%s, expected=%s)", prefix, f.Name, f.Expected, f.Actual)
+	} else {
+		return fmt.Sprintf("%s: checksum mismatch (actual=%s, expected=%s)", prefix, f.Expected, f.Actual)
+	}
+}
+
+// User specified a model type that is not valid
+type UnknownModelTypeError struct {
+	UserError
+	Name string // Name of model
+}
+
+func (f UnknownModelTypeError) Error() string {
+	return fmt.Sprintf("%s: Model %s does not exist. Use `cordctl modeltype list` to get a list of available models", prefix, f.Name)
+}
+
+// User specified a model state that is not valid
+type UnknownModelStateError struct {
+	UserError
+	Name string // Name of state
+}
+
+func (f UnknownModelStateError) Error() string {
+	return fmt.Sprintf("%s: Model state %s does not exist", prefix, f.Name)
+}
+
+// Command requires a filter be specified
+type FilterRequiredError struct {
+	UserError
+}
+
+func (f FilterRequiredError) Error() string {
+	return "Filter required. Use either an ID, --filter, or --all to specify which models to operate on"
+}
+
+// Command was aborted by the user
+type AbortedError struct {
+	UserError
+}
+
+func (f AbortedError) Error() string {
+	return "Aborted"
+}
+
+// Command was aborted by the user
+type NoMatchError struct {
+	UserError
+}
+
+func (f NoMatchError) Error() string {
+	return "No Match"
+}
+
+// User specified a field name that is not valid
+type FieldDoesNotExistError struct {
+	UserError
+	ModelName string
+	FieldName string
+}
+
+func (f FieldDoesNotExistError) Error() string {
+	return fmt.Sprintf("%s: Model %s does not have field %s", prefix, f.ModelName, f.FieldName)
+}
+
+// User specified a query string that is not properly formatted
+type IllegalQueryError struct {
+	UserError
+	Query string
+}
+
+func (f IllegalQueryError) Error() string {
+	return fmt.Sprintf("%s: Illegal query string %s", prefix, f.Query)
+}
+
+// We failed to type convert something that we thought should have converted
+type TypeConversionError struct {
+	UnexpectedError
+	Source      string
+	Destination string
+}
+
+func (f TypeConversionError) Error() string {
+	return fmt.Sprintf("%s: Failed to type convert from %s to %s", prefix, f.Source, f.Destination)
+}
+
+// Version did not match a constraint
+type VersionConstraintError struct {
+	UserError
+	Name       string
+	Version    string
+	Constraint string
+}
+
+func (f VersionConstraintError) Error() string {
+	return fmt.Sprintf("%s: %s version %s did not match constraint '%s'", prefix, f.Name, f.Version, f.Constraint)
+}
+
+// A model was not found
+type ModelNotFoundError struct {
+	UserError
+	ModelName string
+	Id        int32
+	Queries   map[string]string
+}
+
+func (f ModelNotFoundError) Error() string {
+	if f.Queries != nil {
+		return fmt.Sprintf("%s: %s query %v not Found", prefix, f.ModelName, f.Queries)
+	} else {
+		return fmt.Sprintf("%s: Model %s id %d not Found", prefix, f.ModelName, f.Id)
+	}
+}
+
+// InvalidInputError is a catch-all for user mistakes that aren't covered elsewhere
+type InvalidInputError struct {
+	UserError
+	Message string
+}
+
+func (f InvalidInputError) Error() string {
+	return fmt.Sprintf("%s: %s", prefix, f.Message)
+}
+
+func NewInvalidInputError(format string, params ...interface{}) *InvalidInputError {
+	msg := fmt.Sprintf(format, params...)
+	err := &InvalidInputError{Message: msg}
+	err.AddStackTrace(2)
+	return err
+}
+
+// InternalError is a catch-all for errors that don't fit somewhere else
+type InternalError struct {
+	UnexpectedError
+	Message string
+}
+
+func (f InternalError) Error() string {
+	return fmt.Sprintf("%s: %s", prefix, f.Message)
+}
+
+func NewInternalError(format string, params ...interface{}) *InternalError {
+	msg := fmt.Sprintf(format, params...)
+	err := &InternalError{Message: msg}
+	err.AddStackTrace(2)
+	return err
+}
+
+// ***************************************************************************
+// Global exported function declarations
+
+// Attach a stack trace to an error. The error passed in must be a pointer to an error structure for the
+// CordCtlError interface to match.
+func WithStackTrace(err CordCtlError) error {
+	err.AddStackTrace(2)
+	return err
+}
+
+// Set the prefix rather than using os.Args[0]. This is useful for testing.
+func SetPrefix(s string) {
+	prefix = s
+}
+
+// Convert an RPC error into a Cord Error
+func RpcErrorWithIdToCordError(err error, modelName string, id int32) error {
+	if err == nil {
+		return err
+	}
+	if strings.Contains(err.Error(), "rpc error: code = NotFound") {
+		err := &ModelNotFoundError{ModelName: modelName, Id: id}
+		err.AddStackTrace(2)
+		return err
+	}
+	return err
+}
+
+// Module initialization. Automatically defaults prefix to program name
+func init() {
+	prefix = os.Args[0]
+}
diff --git a/error/error_test.go b/error/error_test.go
new file mode 100644
index 0000000..072b74e
--- /dev/null
+++ b/error/error_test.go
@@ -0,0 +1,81 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package error
+
+import (
+	"fmt"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func init() {
+	SetPrefix("cordctl")
+}
+
+func TestGenericError(t *testing.T) {
+	var err error
+
+	err = fmt.Errorf("Some error")
+
+	// Type conversion from `error` to ChecksumMismatchError should fail
+	_, ok := err.(ChecksumMismatchError)
+	assert.False(t, ok)
+
+	// Type conversion from `error` to CordCtlError should fail
+	_, ok = err.(CordCtlError)
+	assert.False(t, ok)
+}
+
+func TestChecksumMismatchError(t *testing.T) {
+	var err error
+
+	err = WithStackTrace(&ChecksumMismatchError{Actual: "123", Expected: "456"})
+
+	//assert.Equal(t, err.(*ChecksumMismatchError).Stack(), "foo")
+
+	// Check that the Error() function returns the right text
+	assert.Equal(t, err.Error(), "cordctl: checksum mismatch (actual=456, expected=123)")
+
+	// Type conversion from `error` to ChecksumMismatchError should succeed
+	_, ok := err.(*ChecksumMismatchError)
+	assert.True(t, ok)
+
+	// Type switch is another way of doing the same
+	switch err.(type) {
+	case *ChecksumMismatchError:
+		// do nothing
+	case CordCtlError:
+		assert.Fail(t, "Should have used the ChecksumMismatchError case instead")
+	default:
+		assert.Fail(t, "Wrong part of switch statement was called")
+	}
+
+	// Type conversion from `error` to CordCtlError should succeed
+	cce, ok := err.(CordCtlError)
+	assert.True(t, ok)
+
+	// ShouldDumpStack() returned from a ChecksumMismatchError should be false
+	assert.False(t, cce.ShouldDumpStack())
+}
+
+func TestUnknownModelTypeError(t *testing.T) {
+	var err error
+
+	err = WithStackTrace(&UnknownModelTypeError{Name: "foo"})
+
+	_ = err
+}
