diff --git a/api.go b/api.go
index 74ffd6dcefa9d4988575917a59a8342e81b387ad..3134acf1b178599b7e452f7132acc79ed9345efb 100644
--- a/api.go
+++ b/api.go
@@ -388,7 +388,7 @@ func registerAPI() {
 			return
 		}
 
-		instance.ImageUpdate(info.Hash, payload.Source, payload.Commentary, payload.CommentaryTranslation)
+		instance.ImageUpdate(info.Hash, payload.Source, payload.Parent, payload.Commentary, payload.CommentaryTranslation)
 	})
 
 	router.DELETE(api.ImageField, func(context *gin.Context) {
diff --git a/api/types.go b/api/types.go
index b2dc5c6c12411af58fca3591f300e32ba1c7b7d2..5c58f0610394cb23226334960bc2e812c7cda40d 100644
--- a/api/types.go
+++ b/api/types.go
@@ -26,6 +26,7 @@ type TagUpdatePayload struct {
 
 type ImageUpdatePayload struct {
 	Source                string `json:"source"`
+	Parent                string `json:"parent"`
 	Commentary            string `json:"commentary"`
 	CommentaryTranslation string `json:"commentary_translation"`
 }
diff --git a/store/image.go b/store/image.go
index 9f82443864394d89106265e22137edf530c272ad..25c093cd99114426375af5caf3542f57f2dae8af 100644
--- a/store/image.go
+++ b/store/image.go
@@ -23,6 +23,7 @@ type Image struct {
 	Type                  string `json:"type"`
 	User                  string `json:"user"`
 	Source                string `json:"source"`
+	Parent                string `json:"parent"`
 	Commentary            string `json:"commentary"`
 	CommentaryTranslation string `json:"commentary_translation"`
 }
@@ -130,7 +131,10 @@ func (s *Store) imageTags(flake string) []string {
 }
 
 // ImageHasTag figures out if an image has a tag.
-func (s *Store) ImageHasTag(flake string, tag string) bool {
+func (s *Store) ImageHasTag(flake, tag string) bool {
+	if !s.flake(flake) || !nameRegex.MatchString(tag) {
+		return false
+	}
 	return s.file(s.ImageTagsPath(flake) + "/" + tag)
 }
 
@@ -278,7 +282,7 @@ func (s *Store) ImageAdd(data []byte, flake string) Image {
 }
 
 // ImageUpdate updates image metadata.
-func (s *Store) ImageUpdate(hash, source, commentary, commentaryTranslation string) {
+func (s *Store) ImageUpdate(hash, source, parent, commentary, commentaryTranslation string) {
 	// Only accept URLs and below 1024 in length
 	if len(source) >= 1024 || !urlRegex.MatchString(source) {
 		return
@@ -302,6 +306,9 @@ func (s *Store) ImageUpdate(hash, source, commentary, commentaryTranslation stri
 	if source != "\000" {
 		info.Source = source
 	}
+	if parent != "\000" && s.ImageSnowflake(parent).Snowflake == parent {
+		info.Parent = parent
+	}
 	if commentary != "\000" {
 		info.Commentary = commentary
 	}
@@ -333,6 +340,10 @@ func (s *Store) ImageSnowflakes() []string {
 
 // ImageSnowflakeHash returns image hash from snowflake.
 func (s *Store) ImageSnowflakeHash(flake string) string {
+	if !s.flake(flake) {
+		return ""
+	}
+
 	if !s.Compat {
 		return s.ImageMetadataRead(s.ImageSnowflakePath(flake) + "/" + infoJson).Hash
 	} else {
diff --git a/store/secret.go b/store/secret.go
index 5941c2f75dfe2414aaecc141f371edc988cb4ed5..10d48d2fb877d43448477bbbe3313b25d1945d63 100644
--- a/store/secret.go
+++ b/store/secret.go
@@ -20,7 +20,7 @@ func (s *Store) SecretNew() string {
 	return string(secret)
 }
 
-// SecretLookup looks up an user from a secret.
+// SecretLookup looks up a user from a secret.
 func (s *Store) SecretLookup(secret string) User {
 	if !secretRegex.MatchString(secret) || !s.file(s.SecretPath(secret)) {
 		return User{}
diff --git a/store/tag.go b/store/tag.go
index 2c11880edb5b9a8c6cd08e7bbbbc82af6923d5ad..dc9073f845e264f9e142395ccbf45adc493eecc8 100644
--- a/store/tag.go
+++ b/store/tag.go
@@ -50,12 +50,12 @@ func (s *Store) Tag(tag string) []string {
 
 // TagCreate creates a tag and returns ok value.
 func (s *Store) TagCreate(tag string) bool {
+	if len(tag) > 128 || !nameRegex.MatchString(tag) {
+		return false
+	}
 	if !s.dir(s.TagPath(tag)) {
 		s.getLock("tag_" + tag).Lock()
 		defer s.getLock("tag_" + tag).Unlock()
-		if len(tag) > 128 || !nameRegex.MatchString(tag) {
-			return false
-		}
 		if err := os.Mkdir(s.TagPath(tag), s.PermissionDir); err != nil {
 			s.fatalClose(fmt.Sprintf("Error creating tag %s, %s", tag, err))
 		}
@@ -127,7 +127,8 @@ func (s *Store) TagType(tag, t string) {
 		t != Generic &&
 		t != Group &&
 		t != Meta {
-		log.Warnf("Invalid tag change on tag %s, got %s, expecting {%s,%s,%s,%s,%s,%s}", tag, t, Artist, Character, Copyright, Generic, Group, Meta)
+		log.Warnf("Invalid tag change on tag %s, got %s, expecting {%s,%s,%s,%s,%s,%s}", tag, t,
+			Artist, Character, Copyright, Generic, Group, Meta)
 		return
 	}
 	info := s.TagInfo(tag)